Source Code Cross Referenced for FileUtils.java in  » Build » ANT » org » apache » tools » ant » 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 » Build » ANT » org.apache.tools.ant.util 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         *  Licensed to the Apache Software Foundation (ASF) under one or more
0003:         *  contributor license agreements.  See the NOTICE file distributed with
0004:         *  this work for additional information regarding copyright ownership.
0005:         *  The ASF licenses this file to You under the Apache License, Version 2.0
0006:         *  (the "License"); you may not use this file except in compliance with
0007:         *  the License.  You may obtain a copy of the License at
0008:         *
0009:         *      http://www.apache.org/licenses/LICENSE-2.0
0010:         *
0011:         *  Unless required by applicable law or agreed to in writing, software
0012:         *  distributed under the License is distributed on an "AS IS" BASIS,
0013:         *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
0014:         *  See the License for the specific language governing permissions and
0015:         *  limitations under the License.
0016:         *
0017:         */
0018:
0019:        package org.apache.tools.ant.util;
0020:
0021:        import java.io.File;
0022:        import java.io.IOException;
0023:        import java.io.InputStream;
0024:        import java.io.InputStreamReader;
0025:        import java.io.Reader;
0026:        import java.io.UnsupportedEncodingException;
0027:        import java.io.Writer;
0028:        import java.io.OutputStream;
0029:        import java.net.MalformedURLException;
0030:        import java.net.URL;
0031:        import java.text.DecimalFormat;
0032:        import java.util.ArrayList;
0033:        import java.util.Arrays;
0034:        import java.util.Iterator;
0035:        import java.util.List;
0036:        import java.util.Random;
0037:        import java.util.Stack;
0038:        import java.util.StringTokenizer;
0039:        import java.util.Vector;
0040:        import org.apache.tools.ant.BuildException;
0041:        import org.apache.tools.ant.PathTokenizer;
0042:        import org.apache.tools.ant.Project;
0043:        import org.apache.tools.ant.taskdefs.condition.Os;
0044:        import org.apache.tools.ant.types.FilterSetCollection;
0045:        import org.apache.tools.ant.types.resources.FileResource;
0046:        import org.apache.tools.ant.launch.Locator;
0047:
0048:        /**
0049:         * This class also encapsulates methods which allow Files to be
0050:         * referred to using abstract path names which are translated to native
0051:         * system file paths at runtime as well as copying files or setting
0052:         * their last modification time.
0053:         *
0054:         */
0055:        public class FileUtils {
0056:
0057:            private static final FileUtils PRIMARY_INSTANCE = new FileUtils();
0058:
0059:            //get some non-crypto-grade randomness from various places.
0060:            private static Random rand = new Random(System.currentTimeMillis()
0061:                    + Runtime.getRuntime().freeMemory());
0062:
0063:            private static boolean onNetWare = Os.isFamily("netware");
0064:            private static boolean onDos = Os.isFamily("dos");
0065:            private static boolean onWin9x = Os.isFamily("win9x");
0066:            private static boolean onWindows = Os.isFamily("windows");
0067:
0068:            static final int BUF_SIZE = 8192;
0069:
0070:            /**
0071:             * The granularity of timestamps under FAT.
0072:             */
0073:            public static final long FAT_FILE_TIMESTAMP_GRANULARITY = 2000;
0074:
0075:            /**
0076:             * The granularity of timestamps under Unix.
0077:             */
0078:            public static final long UNIX_FILE_TIMESTAMP_GRANULARITY = 1000;
0079:
0080:            /**
0081:             * The granularity of timestamps under the NT File System.
0082:             * NTFS has a granularity of 100 nanoseconds, which is less
0083:             * than 1 millisecond, so we round this up to 1 millisecond.
0084:             */
0085:            public static final long NTFS_FILE_TIMESTAMP_GRANULARITY = 1;
0086:
0087:            /**
0088:             * A one item cache for fromUri.
0089:             * fromUri is called for each element when parseing ant build
0090:             * files. It is a costly operation. This just caches the result
0091:             * of the last call.
0092:             */
0093:            private Object cacheFromUriLock = new Object();
0094:            private String cacheFromUriRequest = null;
0095:            private String cacheFromUriResponse = null;
0096:
0097:            /**
0098:             * Factory method.
0099:             *
0100:             * @return a new instance of FileUtils.
0101:             * @deprecated since 1.7.
0102:             *             Use getFileUtils instead,
0103:             * FileUtils do not have state.
0104:             */
0105:            public static FileUtils newFileUtils() {
0106:                return new FileUtils();
0107:            }
0108:
0109:            /**
0110:             * Method to retrieve The FileUtils, which is shared by all users of this
0111:             * method.
0112:             * @return an instance of FileUtils.
0113:             * @since Ant 1.6.3
0114:             */
0115:            public static FileUtils getFileUtils() {
0116:                return PRIMARY_INSTANCE;
0117:            }
0118:
0119:            /**
0120:             * Empty constructor.
0121:             */
0122:            protected FileUtils() {
0123:            }
0124:
0125:            /**
0126:             * Get the URL for a file taking into account # characters.
0127:             *
0128:             * @param file the file whose URL representation is required.
0129:             * @return The FileURL value.
0130:             * @throws MalformedURLException if the URL representation cannot be
0131:             *      formed.
0132:             */
0133:            public URL getFileURL(File file) throws MalformedURLException {
0134:                return new URL(toURI(file.getAbsolutePath()));
0135:            }
0136:
0137:            /**
0138:             * Convenience method to copy a file from a source to a destination.
0139:             * No filtering is performed.
0140:             *
0141:             * @param sourceFile Name of file to copy from.
0142:             *                   Must not be <code>null</code>.
0143:             * @param destFile Name of file to copy to.
0144:             *                 Must not be <code>null</code>.
0145:             *
0146:             * @throws IOException if the copying fails.
0147:             */
0148:            public void copyFile(String sourceFile, String destFile)
0149:                    throws IOException {
0150:                copyFile(new File(sourceFile), new File(destFile), null, false,
0151:                        false);
0152:            }
0153:
0154:            /**
0155:             * Convenience method to copy a file from a source to a destination
0156:             * specifying if token filtering must be used.
0157:             *
0158:             * @param sourceFile Name of file to copy from.
0159:             *                   Must not be <code>null</code>.
0160:             * @param destFile Name of file to copy to.
0161:             *                 Must not be <code>null</code>.
0162:             * @param filters the collection of filters to apply to this copy.
0163:             *
0164:             * @throws IOException if the copying fails.
0165:             */
0166:            public void copyFile(String sourceFile, String destFile,
0167:                    FilterSetCollection filters) throws IOException {
0168:                copyFile(new File(sourceFile), new File(destFile), filters,
0169:                        false, false);
0170:            }
0171:
0172:            /**
0173:             * Convenience method to copy a file from a source to a
0174:             * destination specifying if token filtering must be used and if
0175:             * source files may overwrite newer destination files.
0176:             *
0177:             * @param sourceFile Name of file to copy from.
0178:             *                   Must not be <code>null</code>.
0179:             * @param destFile Name of file to copy to.
0180:             *                 Must not be <code>null</code>.
0181:             * @param filters the collection of filters to apply to this copy.
0182:             * @param overwrite Whether or not the destination file should be
0183:             *                  overwritten if it already exists.
0184:             *
0185:             * @throws IOException if the copying fails.
0186:             */
0187:            public void copyFile(String sourceFile, String destFile,
0188:                    FilterSetCollection filters, boolean overwrite)
0189:                    throws IOException {
0190:                copyFile(new File(sourceFile), new File(destFile), filters,
0191:                        overwrite, false);
0192:            }
0193:
0194:            /**
0195:             * Convenience method to copy a file from a source to a
0196:             * destination specifying if token filtering must be used, if
0197:             * source files may overwrite newer destination files and the
0198:             * last modified time of <code>destFile</code> file should be made equal
0199:             * to the last modified time of <code>sourceFile</code>.
0200:             *
0201:             * @param sourceFile Name of file to copy from.
0202:             *                   Must not be <code>null</code>.
0203:             * @param destFile Name of file to copy to.
0204:             *                 Must not be <code>null</code>.
0205:             * @param filters the collection of filters to apply to this copy.
0206:             * @param overwrite Whether or not the destination file should be
0207:             *                  overwritten if it already exists.
0208:             * @param preserveLastModified Whether or not the last modified time of
0209:             *                             the resulting file should be set to that
0210:             *                             of the source file.
0211:             *
0212:             * @throws IOException if the copying fails.
0213:             */
0214:            public void copyFile(String sourceFile, String destFile,
0215:                    FilterSetCollection filters, boolean overwrite,
0216:                    boolean preserveLastModified) throws IOException {
0217:                copyFile(new File(sourceFile), new File(destFile), filters,
0218:                        overwrite, preserveLastModified);
0219:            }
0220:
0221:            /**
0222:             * Convenience method to copy a file from a source to a
0223:             * destination specifying if token filtering must be used, if
0224:             * source files may overwrite newer destination files and the
0225:             * last modified time of <code>destFile</code> file should be made equal
0226:             * to the last modified time of <code>sourceFile</code>.
0227:             *
0228:             * @param sourceFile Name of file to copy from.
0229:             *                   Must not be <code>null</code>.
0230:             * @param destFile Name of file to copy to.
0231:             *                 Must not be <code>null</code>.
0232:             * @param filters the collection of filters to apply to this copy.
0233:             * @param overwrite Whether or not the destination file should be
0234:             *                  overwritten if it already exists.
0235:             * @param preserveLastModified Whether or not the last modified time of
0236:             *                             the resulting file should be set to that
0237:             *                             of the source file.
0238:             * @param encoding the encoding used to read and write the files.
0239:             *
0240:             * @throws IOException if the copying fails.
0241:             *
0242:             * @since Ant 1.5
0243:             */
0244:            public void copyFile(String sourceFile, String destFile,
0245:                    FilterSetCollection filters, boolean overwrite,
0246:                    boolean preserveLastModified, String encoding)
0247:                    throws IOException {
0248:                copyFile(new File(sourceFile), new File(destFile), filters,
0249:                        overwrite, preserveLastModified, encoding);
0250:            }
0251:
0252:            // CheckStyle:ParameterNumberCheck OFF - bc
0253:            /**
0254:             * Convenience method to copy a file from a source to a
0255:             * destination specifying if token filtering must be used, if
0256:             * filter chains must be used, if source files may overwrite
0257:             * newer destination files and the last modified time of
0258:             * <code>destFile</code> file should be made equal
0259:             * to the last modified time of <code>sourceFile</code>.
0260:             *
0261:             * @param sourceFile Name of file to copy from.
0262:             *                   Must not be <code>null</code>.
0263:             * @param destFile Name of file to copy to.
0264:             *                 Must not be <code>null</code>.
0265:             * @param filters the collection of filters to apply to this copy.
0266:             * @param filterChains filterChains to apply during the copy.
0267:             * @param overwrite Whether or not the destination file should be
0268:             *                  overwritten if it already exists.
0269:             * @param preserveLastModified Whether or not the last modified time of
0270:             *                             the resulting file should be set to that
0271:             *                             of the source file.
0272:             * @param encoding the encoding used to read and write the files.
0273:             * @param project the project instance.
0274:             *
0275:             * @throws IOException if the copying fails.
0276:             *
0277:             * @since Ant 1.5
0278:             */
0279:            public void copyFile(String sourceFile, String destFile,
0280:                    FilterSetCollection filters, Vector filterChains,
0281:                    boolean overwrite, boolean preserveLastModified,
0282:                    String encoding, Project project) throws IOException {
0283:                copyFile(new File(sourceFile), new File(destFile), filters,
0284:                        filterChains, overwrite, preserveLastModified,
0285:                        encoding, project);
0286:            }
0287:
0288:            /**
0289:             * Convenience method to copy a file from a source to a
0290:             * destination specifying if token filtering must be used, if
0291:             * filter chains must be used, if source files may overwrite
0292:             * newer destination files and the last modified time of
0293:             * <code>destFile</code> file should be made equal
0294:             * to the last modified time of <code>sourceFile</code>.
0295:             *
0296:             * @param sourceFile Name of file to copy from.
0297:             *                   Must not be <code>null</code>.
0298:             * @param destFile Name of file to copy to.
0299:             *                 Must not be <code>null</code>.
0300:             * @param filters the collection of filters to apply to this copy.
0301:             * @param filterChains filterChains to apply during the copy.
0302:             * @param overwrite Whether or not the destination file should be
0303:             *                  overwritten if it already exists.
0304:             * @param preserveLastModified Whether or not the last modified time of
0305:             *                             the resulting file should be set to that
0306:             *                             of the source file.
0307:             * @param inputEncoding the encoding used to read the files.
0308:             * @param outputEncoding the encoding used to write the files.
0309:             * @param project the project instance.
0310:             *
0311:             * @throws IOException if the copying fails.
0312:             *
0313:             * @since Ant 1.6
0314:             */
0315:            public void copyFile(String sourceFile, String destFile,
0316:                    FilterSetCollection filters, Vector filterChains,
0317:                    boolean overwrite, boolean preserveLastModified,
0318:                    String inputEncoding, String outputEncoding, Project project)
0319:                    throws IOException {
0320:                copyFile(new File(sourceFile), new File(destFile), filters,
0321:                        filterChains, overwrite, preserveLastModified,
0322:                        inputEncoding, outputEncoding, project);
0323:            }
0324:
0325:            /**
0326:             * Convenience method to copy a file from a source to a destination.
0327:             * No filtering is performed.
0328:             *
0329:             * @param sourceFile the file to copy from.
0330:             *                   Must not be <code>null</code>.
0331:             * @param destFile the file to copy to.
0332:             *                 Must not be <code>null</code>.
0333:             *
0334:             * @throws IOException if the copying fails.
0335:             */
0336:            public void copyFile(File sourceFile, File destFile)
0337:                    throws IOException {
0338:                copyFile(sourceFile, destFile, null, false, false);
0339:            }
0340:
0341:            /**
0342:             * Convenience method to copy a file from a source to a destination
0343:             * specifying if token filtering must be used.
0344:             *
0345:             * @param sourceFile the file to copy from.
0346:             *                   Must not be <code>null</code>.
0347:             * @param destFile the file to copy to.
0348:             *                 Must not be <code>null</code>.
0349:             * @param filters the collection of filters to apply to this copy.
0350:             *
0351:             * @throws IOException if the copying fails.
0352:             */
0353:            public void copyFile(File sourceFile, File destFile,
0354:                    FilterSetCollection filters) throws IOException {
0355:                copyFile(sourceFile, destFile, filters, false, false);
0356:            }
0357:
0358:            /**
0359:             * Convenience method to copy a file from a source to a
0360:             * destination specifying if token filtering must be used and if
0361:             * source files may overwrite newer destination files.
0362:             *
0363:             * @param sourceFile the file to copy from.
0364:             *                   Must not be <code>null</code>.
0365:             * @param destFile the file to copy to.
0366:             *                 Must not be <code>null</code>.
0367:             * @param filters the collection of filters to apply to this copy.
0368:             * @param overwrite Whether or not the destination file should be
0369:             *                  overwritten if it already exists.
0370:             *
0371:             * @throws IOException if the copying fails.
0372:             */
0373:            public void copyFile(File sourceFile, File destFile,
0374:                    FilterSetCollection filters, boolean overwrite)
0375:                    throws IOException {
0376:                copyFile(sourceFile, destFile, filters, overwrite, false);
0377:            }
0378:
0379:            /**
0380:             * Convenience method to copy a file from a source to a
0381:             * destination specifying if token filtering must be used, if
0382:             * source files may overwrite newer destination files and the
0383:             * last modified time of <code>destFile</code> file should be made equal
0384:             * to the last modified time of <code>sourceFile</code>.
0385:             *
0386:             * @param sourceFile the file to copy from.
0387:             *                   Must not be <code>null</code>.
0388:             * @param destFile the file to copy to.
0389:             *                 Must not be <code>null</code>.
0390:             * @param filters the collection of filters to apply to this copy.
0391:             * @param overwrite Whether or not the destination file should be
0392:             *                  overwritten if it already exists.
0393:             * @param preserveLastModified Whether or not the last modified time of
0394:             *                             the resulting file should be set to that
0395:             *                             of the source file.
0396:             *
0397:             * @throws IOException if the copying fails.
0398:             */
0399:            public void copyFile(File sourceFile, File destFile,
0400:                    FilterSetCollection filters, boolean overwrite,
0401:                    boolean preserveLastModified) throws IOException {
0402:                copyFile(sourceFile, destFile, filters, overwrite,
0403:                        preserveLastModified, null);
0404:            }
0405:
0406:            /**
0407:             * Convenience method to copy a file from a source to a
0408:             * destination specifying if token filtering must be used, if
0409:             * source files may overwrite newer destination files, the last
0410:             * modified time of <code>destFile</code> file should be made
0411:             * equal to the last modified time of <code>sourceFile</code> and
0412:             * which character encoding to assume.
0413:             *
0414:             * @param sourceFile the file to copy from.
0415:             *                   Must not be <code>null</code>.
0416:             * @param destFile the file to copy to.
0417:             *                 Must not be <code>null</code>.
0418:             * @param filters the collection of filters to apply to this copy.
0419:             * @param overwrite Whether or not the destination file should be
0420:             *                  overwritten if it already exists.
0421:             * @param preserveLastModified Whether or not the last modified time of
0422:             *                             the resulting file should be set to that
0423:             *                             of the source file.
0424:             * @param encoding the encoding used to read and write the files.
0425:             *
0426:             * @throws IOException if the copying fails.
0427:             *
0428:             * @since Ant 1.5
0429:             */
0430:            public void copyFile(File sourceFile, File destFile,
0431:                    FilterSetCollection filters, boolean overwrite,
0432:                    boolean preserveLastModified, String encoding)
0433:                    throws IOException {
0434:                copyFile(sourceFile, destFile, filters, null, overwrite,
0435:                        preserveLastModified, encoding, null);
0436:            }
0437:
0438:            /**
0439:             * Convenience method to copy a file from a source to a
0440:             * destination specifying if token filtering must be used, if
0441:             * filter chains must be used, if source files may overwrite
0442:             * newer destination files and the last modified time of
0443:             * <code>destFile</code> file should be made equal
0444:             * to the last modified time of <code>sourceFile</code>.
0445:             *
0446:             * @param sourceFile the file to copy from.
0447:             *                   Must not be <code>null</code>.
0448:             * @param destFile the file to copy to.
0449:             *                 Must not be <code>null</code>.
0450:             * @param filters the collection of filters to apply to this copy.
0451:             * @param filterChains filterChains to apply during the copy.
0452:             * @param overwrite Whether or not the destination file should be
0453:             *                  overwritten if it already exists.
0454:             * @param preserveLastModified Whether or not the last modified time of
0455:             *                             the resulting file should be set to that
0456:             *                             of the source file.
0457:             * @param encoding the encoding used to read and write the files.
0458:             * @param project the project instance.
0459:             *
0460:             * @throws IOException if the copying fails.
0461:             *
0462:             * @since Ant 1.5
0463:             */
0464:            public void copyFile(File sourceFile, File destFile,
0465:                    FilterSetCollection filters, Vector filterChains,
0466:                    boolean overwrite, boolean preserveLastModified,
0467:                    String encoding, Project project) throws IOException {
0468:                copyFile(sourceFile, destFile, filters, filterChains,
0469:                        overwrite, preserveLastModified, encoding, encoding,
0470:                        project);
0471:            }
0472:
0473:            /**
0474:             * Convenience method to copy a file from a source to a
0475:             * destination specifying if token filtering must be used, if
0476:             * filter chains must be used, if source files may overwrite
0477:             * newer destination files and the last modified time of
0478:             * <code>destFile</code> file should be made equal
0479:             * to the last modified time of <code>sourceFile</code>.
0480:             *
0481:             * @param sourceFile the file to copy from.
0482:             *                   Must not be <code>null</code>.
0483:             * @param destFile the file to copy to.
0484:             *                 Must not be <code>null</code>.
0485:             * @param filters the collection of filters to apply to this copy.
0486:             * @param filterChains filterChains to apply during the copy.
0487:             * @param overwrite Whether or not the destination file should be
0488:             *                  overwritten if it already exists.
0489:             * @param preserveLastModified Whether or not the last modified time of
0490:             *                             the resulting file should be set to that
0491:             *                             of the source file.
0492:             * @param inputEncoding the encoding used to read the files.
0493:             * @param outputEncoding the encoding used to write the files.
0494:             * @param project the project instance.
0495:             *
0496:             *
0497:             * @throws IOException if the copying fails.
0498:             *
0499:             * @since Ant 1.6
0500:             */
0501:            public void copyFile(File sourceFile, File destFile,
0502:                    FilterSetCollection filters, Vector filterChains,
0503:                    boolean overwrite, boolean preserveLastModified,
0504:                    String inputEncoding, String outputEncoding, Project project)
0505:                    throws IOException {
0506:                ResourceUtils.copyResource(new FileResource(sourceFile),
0507:                        new FileResource(destFile), filters, filterChains,
0508:                        overwrite, preserveLastModified, inputEncoding,
0509:                        outputEncoding, project);
0510:            }
0511:
0512:            // CheckStyle:ParameterNumberCheck ON
0513:
0514:            /**
0515:             * Calls File.setLastModified(long time). Originally written to
0516:             * to dynamically bind to that call on Java1.2+.
0517:             *
0518:             * @param file the file whose modified time is to be set
0519:             * @param time the time to which the last modified time is to be set.
0520:             *             if this is -1, the current time is used.
0521:             */
0522:            public void setFileLastModified(File file, long time) {
0523:                ResourceUtils.setLastModified(new FileResource(file), time);
0524:            }
0525:
0526:            /**
0527:             * Interpret the filename as a file relative to the given file
0528:             * unless the filename already represents an absolute filename.
0529:             * Differs from <code>new File(file, filename)</code> in that
0530:             * the resulting File's path will always be a normalized,
0531:             * absolute pathname.  Also, if it is determined that
0532:             * <code>filename</code> is context-relative, <code>file</code>
0533:             * will be discarded and the reference will be resolved using
0534:             * available context/state information about the filesystem.
0535:             *
0536:             * @param file the "reference" file for relative paths. This
0537:             * instance must be an absolute file and must not contain
0538:             * &quot;./&quot; or &quot;../&quot; sequences (same for \ instead
0539:             * of /).  If it is null, this call is equivalent to
0540:             * <code>new java.io.File(filename).getAbsoluteFile()</code>.
0541:             *
0542:             * @param filename a file name.
0543:             *
0544:             * @return an absolute file.
0545:             * @throws java.lang.NullPointerException if filename is null.
0546:             */
0547:            public File resolveFile(File file, String filename) {
0548:                if (!isAbsolutePath(filename)) {
0549:                    char sep = File.separatorChar;
0550:                    filename = filename.replace('/', sep).replace('\\', sep);
0551:                    if (isContextRelativePath(filename)) {
0552:                        file = null;
0553:                        // on cygwin, our current directory can be a UNC;
0554:                        // assume user.dir is absolute or all hell breaks loose...
0555:                        String udir = System.getProperty("user.dir");
0556:                        if (filename.charAt(0) == sep && udir.charAt(0) == sep) {
0557:                            filename = dissect(udir)[0] + filename.substring(1);
0558:                        }
0559:                    }
0560:                    filename = new File(file, filename).getAbsolutePath();
0561:                }
0562:                return normalize(filename);
0563:            }
0564:
0565:            /**
0566:             * On DOS and NetWare, the evaluation of certain file
0567:             * specifications is context-dependent.  These are filenames
0568:             * beginning with a single separator (relative to current root directory)
0569:             * and filenames with a drive specification and no intervening separator
0570:             * (relative to current directory of the specified root).
0571:             * @param filename the filename to evaluate.
0572:             * @return true if the filename is relative to system context.
0573:             * @throws java.lang.NullPointerException if filename is null.
0574:             * @since Ant 1.7
0575:             */
0576:            public static boolean isContextRelativePath(String filename) {
0577:                if (!(onDos || onNetWare) || filename.length() == 0) {
0578:                    return false;
0579:                }
0580:                char sep = File.separatorChar;
0581:                filename = filename.replace('/', sep).replace('\\', sep);
0582:                char c = filename.charAt(0);
0583:                int len = filename.length();
0584:                return (c == sep && (len == 1 || filename.charAt(1) != sep))
0585:                        || (Character.isLetter(c) && len > 1
0586:                                && filename.indexOf(':') == 1 && (len == 2 || filename
0587:                                .charAt(2) != sep));
0588:            }
0589:
0590:            /**
0591:             * Verifies that the specified filename represents an absolute path.
0592:             * Differs from new java.io.File("filename").isAbsolute() in that a path
0593:             * beginning with a double file separator--signifying a Windows UNC--must
0594:             * at minimum match "\\a\b" to be considered an absolute path.
0595:             * @param filename the filename to be checked.
0596:             * @return true if the filename represents an absolute path.
0597:             * @throws java.lang.NullPointerException if filename is null.
0598:             * @since Ant 1.6.3
0599:             */
0600:            public static boolean isAbsolutePath(String filename) {
0601:                int len = filename.length();
0602:                if (len == 0) {
0603:                    return false;
0604:                }
0605:                char sep = File.separatorChar;
0606:                filename = filename.replace('/', sep).replace('\\', sep);
0607:                char c = filename.charAt(0);
0608:                if (!(onDos || onNetWare)) {
0609:                    return (c == sep);
0610:                }
0611:                if (c == sep) {
0612:                    if (!(onDos && len > 4 && filename.charAt(1) == sep)) {
0613:                        return false;
0614:                    }
0615:                    int nextsep = filename.indexOf(sep, 2);
0616:                    return nextsep > 2 && nextsep + 1 < len;
0617:                }
0618:                int colon = filename.indexOf(':');
0619:                return (Character.isLetter(c) && colon == 1
0620:                        && filename.length() > 2 && filename.charAt(2) == sep)
0621:                        || (onNetWare && colon > 0);
0622:            }
0623:
0624:            /**
0625:             * Translate a path into its native (platform specific) format.
0626:             * <p>
0627:             * This method uses PathTokenizer to separate the input path
0628:             * into its components. This handles DOS style paths in a relatively
0629:             * sensible way. The file separators are then converted to their platform
0630:             * specific versions.
0631:             *
0632:             * @param toProcess The path to be translated.
0633:             *                  May be <code>null</code>.
0634:             *
0635:             * @return the native version of the specified path or
0636:             *         an empty string if the path is <code>null</code> or empty.
0637:             *
0638:             * @since ant 1.7
0639:             * @see PathTokenizer
0640:             */
0641:            public static String translatePath(String toProcess) {
0642:                if (toProcess == null || toProcess.length() == 0) {
0643:                    return "";
0644:                }
0645:                StringBuffer path = new StringBuffer(toProcess.length() + 50);
0646:                PathTokenizer tokenizer = new PathTokenizer(toProcess);
0647:                while (tokenizer.hasMoreTokens()) {
0648:                    String pathComponent = tokenizer.nextToken();
0649:                    pathComponent = pathComponent.replace('/',
0650:                            File.separatorChar);
0651:                    pathComponent = pathComponent.replace('\\',
0652:                            File.separatorChar);
0653:                    if (path.length() != 0) {
0654:                        path.append(File.pathSeparatorChar);
0655:                    }
0656:                    path.append(pathComponent);
0657:                }
0658:                return path.toString();
0659:            }
0660:
0661:            /**
0662:             * &quot;Normalize&quot; the given absolute path.
0663:             *
0664:             * <p>This includes:
0665:             * <ul>
0666:             *   <li>Uppercase the drive letter if there is one.</li>
0667:             *   <li>Remove redundant slashes after the drive spec.</li>
0668:             *   <li>Resolve all ./, .\, ../ and ..\ sequences.</li>
0669:             *   <li>DOS style paths that start with a drive letter will have
0670:             *     \ as the separator.</li>
0671:             * </ul>
0672:             * Unlike {@link File#getCanonicalPath()} this method
0673:             * specifically does not resolve symbolic links.
0674:             *
0675:             * @param path the path to be normalized.
0676:             * @return the normalized version of the path.
0677:             *
0678:             * @throws java.lang.NullPointerException if path is null.
0679:             */
0680:            public File normalize(final String path) {
0681:                Stack s = new Stack();
0682:                String[] dissect = dissect(path);
0683:                s.push(dissect[0]);
0684:
0685:                StringTokenizer tok = new StringTokenizer(dissect[1],
0686:                        File.separator);
0687:                while (tok.hasMoreTokens()) {
0688:                    String this Token = tok.nextToken();
0689:                    if (".".equals(this Token)) {
0690:                        continue;
0691:                    } else if ("..".equals(this Token)) {
0692:                        if (s.size() < 2) {
0693:                            // Cannot resolve it, so skip it.
0694:                            return new File(path);
0695:                        }
0696:                        s.pop();
0697:                    } else { // plain component
0698:                        s.push(this Token);
0699:                    }
0700:                }
0701:                StringBuffer sb = new StringBuffer();
0702:                for (int i = 0; i < s.size(); i++) {
0703:                    if (i > 1) {
0704:                        // not before the filesystem root and not after it, since root
0705:                        // already contains one
0706:                        sb.append(File.separatorChar);
0707:                    }
0708:                    sb.append(s.elementAt(i));
0709:                }
0710:                return new File(sb.toString());
0711:            }
0712:
0713:            /**
0714:             * Dissect the specified absolute path.
0715:             * @param path the path to dissect.
0716:             * @return String[] {root, remaining path}.
0717:             * @throws java.lang.NullPointerException if path is null.
0718:             * @since Ant 1.7
0719:             */
0720:            public String[] dissect(String path) {
0721:                char sep = File.separatorChar;
0722:                path = path.replace('/', sep).replace('\\', sep);
0723:
0724:                // make sure we are dealing with an absolute path
0725:                if (!isAbsolutePath(path)) {
0726:                    throw new BuildException(path + " is not an absolute path");
0727:                }
0728:                String root = null;
0729:                int colon = path.indexOf(':');
0730:                if (colon > 0 && (onDos || onNetWare)) {
0731:
0732:                    int next = colon + 1;
0733:                    root = path.substring(0, next);
0734:                    char[] ca = path.toCharArray();
0735:                    root += sep;
0736:                    //remove the initial separator; the root has it.
0737:                    next = (ca[next] == sep) ? next + 1 : next;
0738:
0739:                    StringBuffer sbPath = new StringBuffer();
0740:                    // Eliminate consecutive slashes after the drive spec:
0741:                    for (int i = next; i < ca.length; i++) {
0742:                        if (ca[i] != sep || ca[i - 1] != sep) {
0743:                            sbPath.append(ca[i]);
0744:                        }
0745:                    }
0746:                    path = sbPath.toString();
0747:                } else if (path.length() > 1 && path.charAt(1) == sep) {
0748:                    // UNC drive
0749:                    int nextsep = path.indexOf(sep, 2);
0750:                    nextsep = path.indexOf(sep, nextsep + 1);
0751:                    root = (nextsep > 2) ? path.substring(0, nextsep + 1)
0752:                            : path;
0753:                    path = path.substring(root.length());
0754:                } else {
0755:                    root = File.separator;
0756:                    path = path.substring(1);
0757:                }
0758:                return new String[] { root, path };
0759:            }
0760:
0761:            /**
0762:             * Returns a VMS String representation of a <code>File</code> object.
0763:             * This is useful since the JVM by default internally converts VMS paths
0764:             * to Unix style.
0765:             * The returned String is always an absolute path.
0766:             *
0767:             * @param f The <code>File</code> to get the VMS path for.
0768:             * @return The absolute VMS path to <code>f</code>.
0769:             */
0770:            public String toVMSPath(File f) {
0771:                // format: "DEVICE:[DIR.SUBDIR]FILE"
0772:                String osPath;
0773:                String path = normalize(f.getAbsolutePath()).getPath();
0774:                String name = f.getName();
0775:                boolean isAbsolute = path.charAt(0) == File.separatorChar;
0776:                // treat directories specified using .DIR syntax as files
0777:                boolean isDirectory = f.isDirectory()
0778:                        && !name.regionMatches(true, name.length() - 4, ".DIR",
0779:                                0, 4);
0780:
0781:                String device = null;
0782:                StringBuffer directory = null;
0783:                String file = null;
0784:
0785:                int index = 0;
0786:
0787:                if (isAbsolute) {
0788:                    index = path.indexOf(File.separatorChar, 1);
0789:                    if (index == -1) {
0790:                        return path.substring(1) + ":[000000]";
0791:                    } else {
0792:                        device = path.substring(1, index++);
0793:                    }
0794:                }
0795:                if (isDirectory) {
0796:                    directory = new StringBuffer(path.substring(index).replace(
0797:                            File.separatorChar, '.'));
0798:                } else {
0799:                    int dirEnd = path.lastIndexOf(File.separatorChar, path
0800:                            .length());
0801:                    if (dirEnd == -1 || dirEnd < index) {
0802:                        file = path.substring(index);
0803:                    } else {
0804:                        directory = new StringBuffer(path.substring(index,
0805:                                dirEnd).replace(File.separatorChar, '.'));
0806:                        index = dirEnd + 1;
0807:                        if (path.length() > index) {
0808:                            file = path.substring(index);
0809:                        }
0810:                    }
0811:                }
0812:                if (!isAbsolute && directory != null) {
0813:                    directory.insert(0, '.');
0814:                }
0815:                osPath = ((device != null) ? device + ":" : "")
0816:                        + ((directory != null) ? "[" + directory + "]" : "")
0817:                        + ((file != null) ? file : "");
0818:                return osPath;
0819:            }
0820:
0821:            /**
0822:             * Create a temporary file in a given directory.
0823:             *
0824:             * <p>The file denoted by the returned abstract pathname did not
0825:             * exist before this method was invoked, any subsequent invocation
0826:             * of this method will yield a different file name.</p>
0827:             * <p>
0828:             * The filename is prefixNNNNNsuffix where NNNN is a random number.
0829:             * </p>
0830:             * <p>This method is different from File.createTempFile() of JDK 1.2
0831:             * as it doesn't create the file itself.  It uses the location pointed
0832:             * to by java.io.tmpdir when the parentDir attribute is null.</p>
0833:             *
0834:             * @param prefix prefix before the random number.
0835:             * @param suffix file extension; include the '.'.
0836:             * @param parentDir Directory to create the temporary file in;
0837:             * java.io.tmpdir used if not specified.
0838:             *
0839:             * @return a File reference to the new temporary file.
0840:             * @since Ant 1.5
0841:             */
0842:            public File createTempFile(String prefix, String suffix,
0843:                    File parentDir) {
0844:                return createTempFile(prefix, suffix, parentDir, false);
0845:            }
0846:
0847:            /**
0848:             * Create a temporary file in a given directory.
0849:             *
0850:             * <p>The file denoted by the returned abstract pathname did not
0851:             * exist before this method was invoked, any subsequent invocation
0852:             * of this method will yield a different file name.</p>
0853:             * <p>
0854:             * The filename is prefixNNNNNsuffix where NNNN is a random number.
0855:             * </p>
0856:             * <p>This method is different from File.createTempFile() of JDK 1.2
0857:             * as it doesn't create the file itself.  It uses the location pointed
0858:             * to by java.io.tmpdir when the parentDir attribute is null.</p>
0859:             *
0860:             * @param prefix prefix before the random number.
0861:             * @param suffix file extension; include the '.'.
0862:             * @param parentDir Directory to create the temporary file in;
0863:             * @param deleteOnExit whether to set the tempfile for deletion on
0864:             *        normal VM exit.
0865:             * java.io.tmpdir used if not specified.
0866:             *
0867:             * @return a File reference to the new temporary file.
0868:             * @since Ant 1.7
0869:             */
0870:            public File createTempFile(String prefix, String suffix,
0871:                    File parentDir, boolean deleteOnExit) {
0872:                File result = null;
0873:                String parent = (parentDir == null) ? System
0874:                        .getProperty("java.io.tmpdir") : parentDir.getPath();
0875:
0876:                DecimalFormat fmt = new DecimalFormat("#####");
0877:                synchronized (rand) {
0878:                    do {
0879:                        result = new File(parent, prefix
0880:                                + fmt.format(Math.abs(rand.nextInt())) + suffix);
0881:                    } while (result.exists());
0882:                }
0883:                if (deleteOnExit) {
0884:                    result.deleteOnExit();
0885:                }
0886:                return result;
0887:            }
0888:
0889:            /**
0890:             * Compares the contents of two files.
0891:             *
0892:             * @param f1 the file whose content is to be compared.
0893:             * @param f2 the other file whose content is to be compared.
0894:             *
0895:             * @return true if the content of the files is the same.
0896:             *
0897:             * @throws IOException if the files cannot be read.
0898:             */
0899:            public boolean contentEquals(File f1, File f2) throws IOException {
0900:                return contentEquals(f1, f2, false);
0901:            }
0902:
0903:            /**
0904:             * Compares the contents of two files.
0905:             *
0906:             * @param f1 the file whose content is to be compared.
0907:             * @param f2 the other file whose content is to be compared.
0908:             * @param textfile true if the file is to be treated as a text file and
0909:             *        differences in kind of line break are to be ignored.
0910:             *
0911:             * @return true if the content of the files is the same.
0912:             *
0913:             * @throws IOException if the files cannot be read.
0914:             * @since Ant 1.6.3
0915:             */
0916:            public boolean contentEquals(File f1, File f2, boolean textfile)
0917:                    throws IOException {
0918:                return ResourceUtils.contentEquals(new FileResource(f1),
0919:                        new FileResource(f2), textfile);
0920:            }
0921:
0922:            /**
0923:             * This was originally an emulation of {@link File#getParentFile} for JDK 1.1,
0924:             * but it is now implemented using that method (Ant 1.6.3 onwards).
0925:             * @param f the file whose parent is required.
0926:             * @return the given file's parent, or null if the file does not have a
0927:             *         parent.
0928:             * @since 1.10
0929:             * @deprecated since 1.7.
0930:             *             Just use {@link File#getParentFile} directly.
0931:             */
0932:            public File getParentFile(File f) {
0933:                return (f == null) ? null : f.getParentFile();
0934:            }
0935:
0936:            /**
0937:             * Read from reader till EOF.
0938:             * @param rdr the reader from which to read.
0939:             * @return the contents read out of the given reader.
0940:             *
0941:             * @throws IOException if the contents could not be read out from the
0942:             *         reader.
0943:             */
0944:            public static final String readFully(Reader rdr) throws IOException {
0945:                return readFully(rdr, BUF_SIZE);
0946:            }
0947:
0948:            /**
0949:             * Read from reader till EOF.
0950:             *
0951:             * @param rdr the reader from which to read.
0952:             * @param bufferSize the buffer size to use when reading.
0953:             *
0954:             * @return the contents read out of the given reader.
0955:             *
0956:             * @throws IOException if the contents could not be read out from the
0957:             *         reader.
0958:             */
0959:            public static final String readFully(Reader rdr, int bufferSize)
0960:                    throws IOException {
0961:                if (bufferSize <= 0) {
0962:                    throw new IllegalArgumentException(
0963:                            "Buffer size must be greater " + "than 0");
0964:                }
0965:                final char[] buffer = new char[bufferSize];
0966:                int bufferLength = 0;
0967:                StringBuffer textBuffer = null;
0968:                while (bufferLength != -1) {
0969:                    bufferLength = rdr.read(buffer);
0970:                    if (bufferLength > 0) {
0971:                        textBuffer = (textBuffer == null) ? new StringBuffer()
0972:                                : textBuffer;
0973:                        textBuffer.append(new String(buffer, 0, bufferLength));
0974:                    }
0975:                }
0976:                return (textBuffer == null) ? null : textBuffer.toString();
0977:            }
0978:
0979:            /**
0980:             * This was originally an emulation of File.createNewFile for JDK 1.1,
0981:             * but it is now implemented using that method (Ant 1.6.3 onwards).
0982:             *
0983:             * <p>This method has historically <strong>not</strong> guaranteed that the
0984:             * operation was atomic. In its current implementation it is.
0985:             *
0986:             * @param f the file to be created.
0987:             * @return true if the file did not exist already.
0988:             * @throws IOException on error.
0989:             * @since Ant 1.5
0990:             */
0991:            public boolean createNewFile(File f) throws IOException {
0992:                return f.createNewFile();
0993:            }
0994:
0995:            /**
0996:             * Create a new file, optionally creating parent directories.
0997:             *
0998:             * @param f the file to be created.
0999:             * @param mkdirs <code>boolean</code> whether to create parent directories.
1000:             * @return true if the file did not exist already.
1001:             * @throws IOException on error.
1002:             * @since Ant 1.6.3
1003:             */
1004:            public boolean createNewFile(File f, boolean mkdirs)
1005:                    throws IOException {
1006:                File parent = f.getParentFile();
1007:                if (mkdirs && !(parent.exists())) {
1008:                    parent.mkdirs();
1009:                }
1010:                return f.createNewFile();
1011:            }
1012:
1013:            /**
1014:             * Checks whether a given file is a symbolic link.
1015:             *
1016:             * <p>It doesn't really test for symbolic links but whether the
1017:             * canonical and absolute paths of the file are identical--this
1018:             * may lead to false positives on some platforms.</p>
1019:             *
1020:             * @param parent the parent directory of the file to test
1021:             * @param name the name of the file to test.
1022:             *
1023:             * @return true if the file is a symbolic link.
1024:             * @throws IOException on error.
1025:             * @since Ant 1.5
1026:             */
1027:            public boolean isSymbolicLink(File parent, String name)
1028:                    throws IOException {
1029:                if (parent == null) {
1030:                    File f = new File(name);
1031:                    parent = f.getParentFile();
1032:                    name = f.getName();
1033:                }
1034:                File toTest = new File(parent.getCanonicalPath(), name);
1035:                return !toTest.getAbsolutePath().equals(
1036:                        toTest.getCanonicalPath());
1037:            }
1038:
1039:            /**
1040:             * Removes a leading path from a second path.
1041:             *
1042:             * @param leading The leading path, must not be null, must be absolute.
1043:             * @param path The path to remove from, must not be null, must be absolute.
1044:             *
1045:             * @return path's normalized absolute if it doesn't start with
1046:             * leading; path's path with leading's path removed otherwise.
1047:             *
1048:             * @since Ant 1.5
1049:             */
1050:            public String removeLeadingPath(File leading, File path) {
1051:                String l = normalize(leading.getAbsolutePath())
1052:                        .getAbsolutePath();
1053:                String p = normalize(path.getAbsolutePath()).getAbsolutePath();
1054:                if (l.equals(p)) {
1055:                    return "";
1056:                }
1057:
1058:                // ensure that l ends with a /
1059:                // so we never think /foo was a parent directory of /foobar
1060:                if (!l.endsWith(File.separator)) {
1061:                    l += File.separator;
1062:                }
1063:                return (p.startsWith(l)) ? p.substring(l.length()) : p;
1064:            }
1065:
1066:            /**
1067:             * Learn whether one path "leads" another.
1068:             * @param leading The leading path, must not be null, must be absolute.
1069:             * @param path The path to remove from, must not be null, must be absolute.
1070:             * @return true if path starts with leading; false otherwise.
1071:             * @since Ant 1.7
1072:             */
1073:            public boolean isLeadingPath(File leading, File path) {
1074:                String l = normalize(leading.getAbsolutePath())
1075:                        .getAbsolutePath();
1076:                String p = normalize(path.getAbsolutePath()).getAbsolutePath();
1077:                if (l.equals(p)) {
1078:                    return true;
1079:                }
1080:                // ensure that l ends with a /
1081:                // so we never think /foo was a parent directory of /foobar
1082:                if (!l.endsWith(File.separator)) {
1083:                    l += File.separator;
1084:                }
1085:                return p.startsWith(l);
1086:            }
1087:
1088:            /**
1089:             * Constructs a <code>file:</code> URI that represents the
1090:             * external form of the given pathname.
1091:             *
1092:             * <p>Will be an absolute URI if the given path is absolute.</p>
1093:             *
1094:             * <p>This code encodes non ASCII characters too.</p>
1095:             *
1096:             * <p>The coding of the output is the same as what File.toURI().toASCIIString() produces</p>
1097:             *
1098:             * See <a href="http://www.w3.org/TR/xml11/#dt-sysid">dt-sysid</a>
1099:             * which makes some mention of how
1100:             * characters not supported by URI Reference syntax should be escaped.
1101:             *
1102:             * @param path the path in the local file system.
1103:             * @return the URI version of the local path.
1104:             * @since Ant 1.6
1105:             */
1106:            public String toURI(String path) {
1107:                // #8031: first try Java 1.4.
1108:                Class uriClazz = null;
1109:                try {
1110:                    uriClazz = Class.forName("java.net.URI");
1111:                } catch (ClassNotFoundException e) {
1112:                    // OK, Java 1.3.
1113:                }
1114:                if (uriClazz != null) {
1115:                    try {
1116:                        File f = new File(path).getAbsoluteFile();
1117:                        java.lang.reflect.Method toURIMethod = File.class
1118:                                .getMethod("toURI", new Class[0]);
1119:                        Object uriObj = toURIMethod.invoke(f, new Object[] {});
1120:                        java.lang.reflect.Method toASCIIStringMethod = uriClazz
1121:                                .getMethod("toASCIIString", new Class[0]);
1122:                        return (String) toASCIIStringMethod.invoke(uriObj,
1123:                                new Object[] {});
1124:                    } catch (Exception e) {
1125:                        // Reflection problems? Should not happen, debug.
1126:                        e.printStackTrace();
1127:                    }
1128:                }
1129:                boolean isDir = new File(path).isDirectory();
1130:
1131:                StringBuffer sb = new StringBuffer("file:");
1132:
1133:                path = resolveFile(null, path).getPath();
1134:                sb.append("//");
1135:                // add an extra slash for filesystems with drive-specifiers
1136:                if (!path.startsWith(File.separator)) {
1137:                    sb.append("/");
1138:                }
1139:                path = path.replace('\\', '/');
1140:                try {
1141:                    sb.append(Locator.encodeURI(path));
1142:                } catch (UnsupportedEncodingException exc) {
1143:                    throw new BuildException(exc);
1144:                }
1145:                if (isDir && !path.endsWith("/")) {
1146:                    sb.append('/');
1147:                }
1148:                return sb.toString();
1149:            }
1150:
1151:            /**
1152:             * Constructs a file path from a <code>file:</code> URI.
1153:             *
1154:             * <p>Will be an absolute path if the given URI is absolute.</p>
1155:             *
1156:             * <p>Swallows '%' that are not followed by two characters,
1157:             * doesn't deal with non-ASCII characters.</p>
1158:             *
1159:             * @param uri the URI designating a file in the local filesystem.
1160:             * @return the local file system path for the file.
1161:             * @since Ant 1.6
1162:             */
1163:            public String fromURI(String uri) {
1164:                synchronized (cacheFromUriLock) {
1165:                    if (uri.equals(cacheFromUriRequest)) {
1166:                        return cacheFromUriResponse;
1167:                    }
1168:                    String path = Locator.fromURI(uri);
1169:                    String ret = isAbsolutePath(path) ? normalize(path)
1170:                            .getAbsolutePath() : path;
1171:                    cacheFromUriRequest = uri;
1172:                    cacheFromUriResponse = ret;
1173:                    return ret;
1174:                }
1175:            }
1176:
1177:            /**
1178:             * Compares two filenames.
1179:             *
1180:             * <p>Unlike java.io.File#equals this method will try to compare
1181:             * the absolute paths and &quot;normalize&quot; the filenames
1182:             * before comparing them.</p>
1183:             *
1184:             * @param f1 the file whose name is to be compared.
1185:             * @param f2 the other file whose name is to be compared.
1186:             *
1187:             * @return true if the file are for the same file.
1188:             *
1189:             * @since Ant 1.5.3
1190:             */
1191:            public boolean fileNameEquals(File f1, File f2) {
1192:                return normalize(f1.getAbsolutePath()).equals(
1193:                        normalize(f2.getAbsolutePath()));
1194:            }
1195:
1196:            /**
1197:             * Renames a file, even if that involves crossing file system boundaries.
1198:             *
1199:             * <p>This will remove <code>to</code> (if it exists), ensure that
1200:             * <code>to</code>'s parent directory exists and move
1201:             * <code>from</code>, which involves deleting <code>from</code> as
1202:             * well.</p>
1203:             *
1204:             * @param from the file to move.
1205:             * @param to the new file name.
1206:             *
1207:             * @throws IOException if anything bad happens during this
1208:             * process.  Note that <code>to</code> may have been deleted
1209:             * already when this happens.
1210:             *
1211:             * @since Ant 1.6
1212:             */
1213:            public void rename(File from, File to) throws IOException {
1214:                if (to.exists() && !to.delete()) {
1215:                    throw new IOException("Failed to delete " + to
1216:                            + " while trying to rename " + from);
1217:                }
1218:                File parent = to.getParentFile();
1219:                if (parent != null && !parent.exists() && !parent.mkdirs()) {
1220:                    throw new IOException("Failed to create directory "
1221:                            + parent + " while trying to rename " + from);
1222:                }
1223:                if (!from.renameTo(to)) {
1224:                    copyFile(from, to);
1225:                    if (!from.delete()) {
1226:                        throw new IOException("Failed to delete " + from
1227:                                + " while trying to rename it.");
1228:                    }
1229:                }
1230:            }
1231:
1232:            /**
1233:             * Get the granularity of file timestamps.
1234:             * The choice is made based on OS, which is incorrect--it should really be
1235:             * by filesystem. We do not have an easy way to probe for file systems,
1236:             * however, so this heuristic gives us a decent default.
1237:             * @return the difference, in milliseconds, which two file timestamps must have
1238:             * in order for the two files to be considered to have different timestamps.
1239:             */
1240:            public long getFileTimestampGranularity() {
1241:                if (onWin9x) {
1242:                    return FAT_FILE_TIMESTAMP_GRANULARITY;
1243:                } else if (onWindows) {
1244:                    return NTFS_FILE_TIMESTAMP_GRANULARITY;
1245:                } else if (onDos) {
1246:                    return FAT_FILE_TIMESTAMP_GRANULARITY;
1247:                }
1248:                return UNIX_FILE_TIMESTAMP_GRANULARITY;
1249:            }
1250:
1251:            /**
1252:             * Returns true if the source is older than the dest.
1253:             * If the dest file does not exist, then the test returns false; it is
1254:             * implicitly not up do date.
1255:             * @param source source file (should be the older).
1256:             * @param dest dest file (should be the newer).
1257:             * @param granularity an offset added to the source time.
1258:             * @return true if the source is older than the dest after accounting
1259:             *              for granularity.
1260:             * @since Ant 1.6.3
1261:             */
1262:            public boolean isUpToDate(File source, File dest, long granularity) {
1263:                //do a check for the destination file existing
1264:                if (!dest.exists()) {
1265:                    //if it does not, then the file is not up to date.
1266:                    return false;
1267:                }
1268:                long sourceTime = source.lastModified();
1269:                long destTime = dest.lastModified();
1270:                return isUpToDate(sourceTime, destTime, granularity);
1271:            }
1272:
1273:            /**
1274:             * Returns true if the source is older than the dest.
1275:             * @param source source file (should be the older).
1276:             * @param dest dest file (should be the newer).
1277:             * @return true if the source is older than the dest, taking the granularity into account.
1278:             * @since Ant 1.6.3
1279:             */
1280:            public boolean isUpToDate(File source, File dest) {
1281:                return isUpToDate(source, dest, getFileTimestampGranularity());
1282:            }
1283:
1284:            /**
1285:             * Compare two timestamps for being up to date using
1286:             * the specified granularity.
1287:             *
1288:             * @param sourceTime timestamp of source file.
1289:             * @param destTime timestamp of dest file.
1290:             * @param granularity os/filesys granularity.
1291:             * @return true if the dest file is considered up to date.
1292:             */
1293:            public boolean isUpToDate(long sourceTime, long destTime,
1294:                    long granularity) {
1295:                if (destTime == -1) {
1296:                    return false;
1297:                }
1298:                return destTime >= sourceTime + granularity;
1299:            }
1300:
1301:            /**
1302:             * Compare two timestamps for being up to date using the
1303:             * current granularity.
1304:             *
1305:             * @param sourceTime  timestamp of source file.
1306:             * @param destTime    timestamp of dest file.
1307:             * @return true if the dest file is considered up to date.
1308:             */
1309:            public boolean isUpToDate(long sourceTime, long destTime) {
1310:                return isUpToDate(sourceTime, destTime,
1311:                        getFileTimestampGranularity());
1312:            }
1313:
1314:            /**
1315:             * Close a Writer without throwing any exception if something went wrong.
1316:             * Do not attempt to close it if the argument is null.
1317:             * @param device output writer, can be null.
1318:             */
1319:            public static void close(Writer device) {
1320:                if (device != null) {
1321:                    try {
1322:                        device.close();
1323:                    } catch (IOException ioex) {
1324:                        //ignore
1325:                    }
1326:                }
1327:            }
1328:
1329:            /**
1330:             * Close a stream without throwing any exception if something went wrong.
1331:             * Do not attempt to close it if the argument is null.
1332:             *
1333:             * @param device Reader, can be null.
1334:             */
1335:            public static void close(Reader device) {
1336:                if (device != null) {
1337:                    try {
1338:                        device.close();
1339:                    } catch (IOException ioex) {
1340:                        //ignore
1341:                    }
1342:                }
1343:            }
1344:
1345:            /**
1346:             * Close a stream without throwing any exception if something went wrong.
1347:             * Do not attempt to close it if the argument is null.
1348:             *
1349:             * @param device stream, can be null.
1350:             */
1351:            public static void close(OutputStream device) {
1352:                if (device != null) {
1353:                    try {
1354:                        device.close();
1355:                    } catch (IOException ioex) {
1356:                        //ignore
1357:                    }
1358:                }
1359:            }
1360:
1361:            /**
1362:             * Close a stream without throwing any exception if something went wrong.
1363:             * Do not attempt to close it if the argument is null.
1364:             *
1365:             * @param device stream, can be null.
1366:             */
1367:            public static void close(InputStream device) {
1368:                if (device != null) {
1369:                    try {
1370:                        device.close();
1371:                    } catch (IOException ioex) {
1372:                        //ignore
1373:                    }
1374:                }
1375:            }
1376:
1377:            /**
1378:             * Delete the file with {@link File#delete()} if the argument is not null.
1379:             * Do nothing on a null argument.
1380:             * @param file file to delete.
1381:             */
1382:            public static void delete(File file) {
1383:                if (file != null) {
1384:                    file.delete();
1385:                }
1386:            }
1387:
1388:            /**
1389:             * Calculates the relative path between two files.
1390:             * <p>
1391:             * Implementation note:<br/> This function my throw an IOException if an
1392:             * I/O error occurs because its use of the canonical pathname may require
1393:             * filesystem queries.
1394:             * </p>
1395:             *
1396:             * @param fromFile
1397:             *            the <code>File</code> to calculate the path from
1398:             * @param toFile
1399:             *            the <code>File</code> to calculate the path to
1400:             * @return the relative path between the files
1401:             * @throws Exception for undocumented reasons
1402:             * @see File#getCanonicalPath()
1403:             *
1404:             * @since Ant 1.7
1405:             */
1406:            public static String getRelativePath(File fromFile, File toFile)
1407:                    throws Exception {
1408:                String fromPath = fromFile.getCanonicalPath();
1409:                String toPath = toFile.getCanonicalPath();
1410:
1411:                // build the path stack info to compare
1412:                String[] fromPathStack = getPathStack(fromPath);
1413:                String[] toPathStack = getPathStack(toPath);
1414:
1415:                if (0 < toPathStack.length && 0 < fromPathStack.length) {
1416:                    if (!fromPathStack[0].equals(toPathStack[0])) {
1417:                        // not the same device (would be "" on Linux/Unix)
1418:
1419:                        return getPath(Arrays.asList(toPathStack));
1420:                    }
1421:                } else {
1422:                    // no comparison possible
1423:                    return getPath(Arrays.asList(toPathStack));
1424:                }
1425:
1426:                int minLength = Math.min(fromPathStack.length,
1427:                        toPathStack.length);
1428:
1429:                int same = 1;
1430:
1431:                // get index of parts which are equal
1432:                for (; same < minLength; same++) {
1433:                    if (!fromPathStack[same].equals(toPathStack[same])) {
1434:                        break;
1435:                    }
1436:                }
1437:
1438:                List relativePathStack = new ArrayList();
1439:
1440:                // if "from" part is longer, fill it up with ".."
1441:                // to reach path which is equal to both paths
1442:                for (int i = same; i < fromPathStack.length; i++) {
1443:                    relativePathStack.add("..");
1444:                }
1445:
1446:                // fill it up path with parts which were not equal
1447:                for (int i = same; i < toPathStack.length; i++) {
1448:                    relativePathStack.add(toPathStack[i]);
1449:                }
1450:
1451:                return getPath(relativePathStack);
1452:            }
1453:
1454:            /**
1455:             * Gets all names of the path as an array of <code>String</code>s.
1456:             *
1457:             * @param path
1458:             *            to get names from
1459:             * @return <code>String</code>s, never <code>null</code>
1460:             *
1461:             * @since Ant 1.7
1462:             */
1463:            public static String[] getPathStack(String path) {
1464:                String normalizedPath = path.replace(File.separatorChar, '/');
1465:
1466:                // since Java 1.4
1467:                //return normalizedPath.split("/");
1468:                // workaround for Java 1.2-1.3
1469:                Object[] tokens = StringUtils.split(normalizedPath, '/')
1470:                        .toArray();
1471:                String[] rv = new String[tokens.length];
1472:                System.arraycopy(tokens, 0, rv, 0, tokens.length);
1473:
1474:                return rv;
1475:            }
1476:
1477:            /**
1478:             * Gets path from a <code>List</code> of <code>String</code>s.
1479:             *
1480:             * @param pathStack
1481:             *            <code>List</code> of <code>String</code>s to be concated
1482:             *            as a path.
1483:             * @return <code>String</code>, never <code>null</code>
1484:             *
1485:             * @since Ant 1.7
1486:             */
1487:            public static String getPath(List pathStack) {
1488:                // can safely use '/' because Windows understands '/' as separator
1489:                return getPath(pathStack, '/');
1490:            }
1491:
1492:            /**
1493:             * Gets path from a <code>List</code> of <code>String</code>s.
1494:             *
1495:             * @param pathStack
1496:             *            <code>List</code> of <code>String</code>s to be concated
1497:             *            as a path.
1498:             * @param separatorChar
1499:             *            <code>char</code> to be used as separator between names in
1500:             *            path
1501:             * @return <code>String</code>, never <code>null</code>
1502:             *
1503:             * @since Ant 1.7
1504:             */
1505:            public static String getPath(final List pathStack,
1506:                    final char separatorChar) {
1507:                final StringBuffer buffer = new StringBuffer();
1508:
1509:                final Iterator iter = pathStack.iterator();
1510:                if (iter.hasNext()) {
1511:                    buffer.append(iter.next());
1512:                }
1513:
1514:                while (iter.hasNext()) {
1515:                    buffer.append(separatorChar);
1516:                    buffer.append(iter.next());
1517:                }
1518:
1519:                return buffer.toString();
1520:            }
1521:
1522:            /**
1523:             * Get the default encoding.
1524:             * This is done by opening an InputStreamReader on
1525:             * a dummy InputStream and getting the encoding.
1526:             * Could use System.getProperty("file.encoding"), but cannot
1527:             * see where this is documented.
1528:             * @return the default file encoding.
1529:             */
1530:            public String getDefaultEncoding() {
1531:                InputStreamReader is = new InputStreamReader(new InputStream() {
1532:                    public int read() {
1533:                        return -1;
1534:                    }
1535:                });
1536:                try {
1537:                    return is.getEncoding();
1538:                } finally {
1539:                    close(is);
1540:                }
1541:            }
1542:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.