Source Code Cross Referenced for FileTools.java in  » PDF » jPod » de » intarsys » tools » file » 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 » PDF » jPod » de.intarsys.tools.file 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * Copyright (c) 2007, intarsys consulting GmbH
0003:         *
0004:         * Redistribution and use in source and binary forms, with or without
0005:         * modification, are permitted provided that the following conditions are met:
0006:         *
0007:         * - Redistributions of source code must retain the above copyright notice,
0008:         *   this list of conditions and the following disclaimer.
0009:         *
0010:         * - Redistributions in binary form must reproduce the above copyright notice,
0011:         *   this list of conditions and the following disclaimer in the documentation
0012:         *   and/or other materials provided with the distribution.
0013:         *
0014:         * - Neither the name of intarsys nor the names of its contributors may be used
0015:         *   to endorse or promote products derived from this software without specific
0016:         *   prior written permission.
0017:         *
0018:         * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
0019:         * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
0020:         * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
0021:         * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
0022:         * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
0023:         * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
0024:         * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
0025:         * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
0026:         * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
0027:         * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
0028:         * POSSIBILITY OF SUCH DAMAGE.
0029:         */
0030:        package de.intarsys.tools.file;
0031:
0032:        import java.io.File;
0033:        import java.io.FileInputStream;
0034:        import java.io.FileOutputStream;
0035:        import java.io.FileWriter;
0036:        import java.io.IOException;
0037:        import java.io.InputStream;
0038:        import java.io.Writer;
0039:        import java.net.URL;
0040:        import java.util.ArrayList;
0041:        import java.util.List;
0042:        import de.intarsys.tools.stream.StreamTools;
0043:        import de.intarsys.tools.string.StringTools;
0044:
0045:        /**
0046:         * Some utility methods to ease life with File's
0047:         */
0048:        public class FileTools {
0049:            // 
0050:            public static final int MAX_BUFFER = 10000;
0051:
0052:            /**
0053:             * Concatenate the two files given in <code>source</code> and
0054:             * <code>destination</code>.
0055:             * 
0056:             * @param source
0057:             *            The file to be appended.
0058:             * @param destination
0059:             *            The file to append to.
0060:             * 
0061:             * @throws IOException
0062:             */
0063:            public static void appendFile(File source, File destination)
0064:                    throws IOException {
0065:                FileInputStream is = null;
0066:                FileOutputStream os = null;
0067:                if (fileTheSame(source, destination)) {
0068:                    return;
0069:                }
0070:                try {
0071:                    is = new FileInputStream(source);
0072:                    os = new FileOutputStream(destination.getAbsolutePath(),
0073:                            true);
0074:                    // todo use StreamTools
0075:                    byte[] b = new byte[MAX_BUFFER];
0076:                    for (int i = is.read(b); i != -1;) {
0077:                        os.write(b, 0, i);
0078:                        i = is.read(b);
0079:                    }
0080:                } catch (Exception e) {
0081:                    throw new IOException("copying failed (" + e.getMessage()
0082:                            + ")");
0083:                } finally {
0084:                    try {
0085:                        if (is != null) {
0086:                            is.close();
0087:                        }
0088:                    } catch (Exception ignore) {
0089:                        // ignore failure
0090:                    }
0091:                    try {
0092:                        if (os != null) {
0093:                            os.close();
0094:                        }
0095:                    } catch (Exception ignore) {
0096:                        // ignore failure
0097:                    }
0098:                }
0099:            }
0100:
0101:            /**
0102:             * Utility method for checking the availablity of a directory.
0103:             * 
0104:             * @param dir
0105:             *            The directory to check.
0106:             * @param create
0107:             *            Flag if we should create if dir not already exists.
0108:             * @param checkCanRead
0109:             *            Flag if we should check read permission.
0110:             * @param checkCanWrite
0111:             *            Flag if we should check write permission.
0112:             * 
0113:             * @return The checked directory.
0114:             * 
0115:             * @throws IOException
0116:             */
0117:            public static File checkDirectory(File dir, boolean create,
0118:                    boolean checkCanRead, boolean checkCanWrite)
0119:                    throws IOException {
0120:                if (dir == null) {
0121:                    return dir;
0122:                }
0123:                if (!dir.exists() && create) {
0124:                    if (!dir.mkdirs()) {
0125:                        throw new IOException("Can't create directory "
0126:                                + dir.getPath());
0127:                    }
0128:                }
0129:                if (!dir.exists()) {
0130:                    throw new IOException("Can't create directory "
0131:                            + dir.getPath());
0132:                }
0133:                if (!dir.isDirectory()) {
0134:                    throw new IOException("Can't create directory "
0135:                            + dir.getPath());
0136:                }
0137:                if (checkCanRead && !dir.canRead()) {
0138:                    throw new IOException("No read access for directory "
0139:                            + dir.getPath());
0140:                }
0141:                if (checkCanWrite && !dir.canWrite()) {
0142:                    throw new IOException("No write access for directory "
0143:                            + dir.getPath());
0144:                }
0145:                return dir;
0146:            }
0147:
0148:            /**
0149:             * @see #checkDirectory(File, boolean, boolean, boolean)
0150:             */
0151:            public static File checkDirectory(String path, boolean create,
0152:                    boolean checkCanRead, boolean checkCanWrite)
0153:                    throws IOException {
0154:                File file = new File(path);
0155:                return checkDirectory(file, create, checkCanRead, checkCanWrite);
0156:            }
0157:
0158:            /**
0159:             * Copy the byte content of <code>source</code> to
0160:             * <code>destination</code>.
0161:             * 
0162:             * @param source
0163:             *            The file whose contents we should copy.
0164:             * @param destination
0165:             *            The file where the contents are copied to.
0166:             * 
0167:             * @throws IOException
0168:             */
0169:            public static void copyBinaryFile(File source, File destination)
0170:                    throws IOException {
0171:                // todo move to stream
0172:                if (!destination.getParentFile().exists()) {
0173:                    destination.getParentFile().mkdirs();
0174:                }
0175:                FileInputStream is = null;
0176:                FileOutputStream os = null;
0177:                try {
0178:                    is = new FileInputStream(source);
0179:                    os = new FileOutputStream(destination);
0180:                    StreamTools.copyStream(is, os);
0181:                } finally {
0182:                    StreamTools.close(is);
0183:                    StreamTools.close(os);
0184:                }
0185:                destination.setLastModified(source.lastModified());
0186:            }
0187:
0188:            /**
0189:             * @see #copyBinaryFile(File, File)
0190:             */
0191:            public static void copyFile(File source, File destination)
0192:                    throws IOException {
0193:                copyBinaryFile(source, destination);
0194:            }
0195:
0196:            /**
0197:             * Copy the character content of <code>source</code> to
0198:             * <code>destination</code>.
0199:             * 
0200:             * @param source
0201:             *            The file whose contents we should copy.
0202:             * @param sourceEncoding
0203:             *            The encoding of the source byte stream.
0204:             * @param destination
0205:             *            The file where the contents are copied to.
0206:             * @param destinationEncoding
0207:             *            The encoding of the destination byte stream.
0208:             * 
0209:             * @throws IOException
0210:             */
0211:            public static void copyFile(File source, String sourceEncoding,
0212:                    File destination, String destinationEncoding)
0213:                    throws IOException {
0214:                // todo move to stream
0215:                if ((sourceEncoding == null) || (destinationEncoding == null)
0216:                        || sourceEncoding.equals(destinationEncoding)) {
0217:                    copyBinaryFile(source, destination);
0218:                    return;
0219:                }
0220:
0221:                if (!destination.getParentFile().exists()) {
0222:                    destination.getParentFile().mkdirs();
0223:                }
0224:                FileInputStream is = null;
0225:                FileOutputStream os = null;
0226:                try {
0227:                    is = new FileInputStream(source);
0228:                    os = new FileOutputStream(destination);
0229:                    StreamTools.copyEncodedStream(is, sourceEncoding, os,
0230:                            destinationEncoding);
0231:                } catch (Exception e) {
0232:                    throw new IOException("copying failed (" + e.getMessage()
0233:                            + ")");
0234:                } finally {
0235:                    StreamTools.close(is);
0236:                    StreamTools.close(os);
0237:                }
0238:            }
0239:
0240:            public static void copyRecursively(File source, File destination)
0241:                    throws IOException {
0242:                if (source.isFile()) {
0243:                    copyFile(source, destination);
0244:                    return;
0245:                }
0246:                if (!source.isDirectory()) {
0247:                    throw new IOException("file '" + source.getAbsolutePath()
0248:                            + "' does not exist.");
0249:                }
0250:                if (destination.isFile()) {
0251:                    throw new IOException("cannot copy directory into file");
0252:                }
0253:                destination.mkdirs();
0254:                String[] content = source.list();
0255:                for (int i = 0; i < content.length; i++) {
0256:                    copyRecursively(new File(source, content[i]), new File(
0257:                            destination, content[i]));
0258:                }
0259:            }
0260:
0261:            public static File copyRecursivelyInto(File source,
0262:                    File destinationParent, String newName) throws IOException {
0263:                if (destinationParent.isFile()) {
0264:                    throw new IOException("can't copy into file");
0265:                }
0266:                String destinationName;
0267:                if (newName == null) {
0268:                    destinationName = source.getName();
0269:                } else {
0270:                    destinationName = newName;
0271:                }
0272:                File destinationFile = new File(destinationParent,
0273:                        destinationName);
0274:                if (source.equals(destinationFile)) {
0275:                    return destinationFile;
0276:                }
0277:                if (source.isFile()) {
0278:                    copyFile(source, destinationFile);
0279:                    return destinationFile;
0280:                }
0281:                if (!source.isDirectory()) {
0282:                    throw new IOException("file '" + source.getAbsolutePath()
0283:                            + "' does not exist.");
0284:                }
0285:                String[] content = source.list();
0286:                // play safe - list before creating directory (no recursion)
0287:                destinationFile.mkdirs();
0288:                for (int i = 0; i < content.length; i++) {
0289:                    copyRecursivelyInto(new File(source, content[i]),
0290:                            destinationFile, content[i]);
0291:                }
0292:                return destinationFile;
0293:            }
0294:
0295:            /**
0296:             * Create a file object representing a temporary file in the user's temp dir
0297:             * with the same name as the given file.
0298:             * 
0299:             * @param file
0300:             *            filename to use
0301:             * @returns file object representing a temporary file
0302:             */
0303:            public static File createTempFile(File file) throws IOException {
0304:                String name;
0305:                String extension;
0306:                int index;
0307:
0308:                name = file.getName();
0309:                index = name.lastIndexOf('.');
0310:                if (index >= 0) {
0311:                    extension = name.substring(index);
0312:                    name = name.substring(0, index);
0313:                } else {
0314:                    extension = StringTools.EMPTY;
0315:                }
0316:                if (name.length() < 3) {
0317:                    name = "tmp" + name;
0318:                }
0319:                return File.createTempFile(name, extension);
0320:            }
0321:
0322:            /**
0323:             * Create a file object representing a temporary file in the user's temp dir
0324:             * with the given filename. Does not actually create a file in the file
0325:             * system.
0326:             * 
0327:             * @param filename
0328:             *            filename to use
0329:             * @returns file object representing a temporary file
0330:             */
0331:            public static File createTempFile(String fileName)
0332:                    throws IOException {
0333:                return createTempFile(new File(fileName));
0334:            }
0335:
0336:            /**
0337:             * Delete any file in <code>directory</code> that is older than
0338:             * <code>millis</code> milliseconds. When <code>recursiveScan</code> is
0339:             * <code>true</code> the directory lookup is made recursive.
0340:             * 
0341:             * @param directory
0342:             *            The directory to scan.
0343:             * @param millis
0344:             *            The number of milliseconds a file is allowed to live.
0345:             * @param recursiveScan
0346:             *            Flag if we should handle directories recursive.
0347:             * 
0348:             * @throws IOException
0349:             */
0350:            public static void deleteAfter(File directory, long millis,
0351:                    boolean recursiveScan) throws IOException {
0352:                if (millis <= 0) {
0353:                    return;
0354:                }
0355:
0356:                String[] fileNames = directory.list();
0357:                if (fileNames == null) {
0358:                    throw new IOException("can not list " + directory);
0359:                }
0360:
0361:                long checkMillis = System.currentTimeMillis() - millis;
0362:                for (int j = 0; j < fileNames.length; j++) {
0363:                    File file = new File(directory, fileNames[j]);
0364:                    if (file.isDirectory() && recursiveScan) {
0365:                        deleteAfter(file, millis, recursiveScan);
0366:                    }
0367:                    if (file.lastModified() < checkMillis) {
0368:                        file.delete();
0369:                    }
0370:                }
0371:            }
0372:
0373:            /**
0374:             * Deletes a file or directory, if necessary recursivly.
0375:             * 
0376:             * <p>
0377:             * Returns <code>true</code> if file could be deleted inclusive its
0378:             * components, otherwise false.
0379:             * </p>
0380:             * 
0381:             * @param file
0382:             *            The file or directory to delete.
0383:             * 
0384:             * @return <code>true</code> if file could be deleted inclusive its
0385:             *         components, otherwise false.
0386:             */
0387:            public static boolean deleteRecursivly(File file) {
0388:                return deleteRecursivly(file, true);
0389:            }
0390:
0391:            /**
0392:             * Deletes a file or directory, if necessary recursivly.
0393:             * 
0394:             * <p>
0395:             * Returns <code>true</code> if file could be deleted inclusive its
0396:             * components, otherwise false.
0397:             * </p>
0398:             * 
0399:             * @param file
0400:             *            The file or directory to delete.
0401:             * @param deleteRoot
0402:             *            Flag if the root directory should be deleted itself.
0403:             * 
0404:             * @return <code>true</code> if file could be deleted inclusive its
0405:             *         components, otherwise false.
0406:             */
0407:            public static boolean deleteRecursivly(File file, boolean deleteRoot) {
0408:                if (!file.exists()) {
0409:                    return true;
0410:                }
0411:                if (file.isFile()) {
0412:                    return file.delete();
0413:                }
0414:                String[] files = file.list();
0415:                if (files == null) {
0416:                    return false;
0417:                }
0418:                if (files.length == 0) {
0419:                    return file.delete();
0420:                }
0421:                for (int i = 0; i < files.length; i++) {
0422:                    if (!deleteRecursivly(new File(file, files[i]))) {
0423:                        return false;
0424:                    }
0425:                }
0426:                if (deleteRoot) {
0427:                    return file.delete();
0428:                }
0429:                return true;
0430:            }
0431:
0432:            /**
0433:             * Archive a files content.
0434:             * 
0435:             * <p>
0436:             * The method creates a copy in the archive directory with a unique name
0437:             * that is guaranteed to create a sortable representation so that newer
0438:             * files have a "greater" filename. Creation of file names is thread safe.
0439:             * If more than <code>max</code> files are in the archive directory, the
0440:             * oldest files are deleted. max = 0 means never create archive, max = -1
0441:             * means always create archive. If <code>deleteSource</code> is
0442:             * <code>true</code>, the file to be archived is deleted after the
0443:             * archive was created.
0444:             * </p>
0445:             * 
0446:             * @param file
0447:             *            The file to archive.
0448:             * @param root
0449:             *            The root for relative addressing.
0450:             * @param relativePath
0451:             *            The path relative to root where to create the archive.
0452:             * @param max
0453:             *            The maximum number of archive files allowed.han
0454:             * @param sourceEncoding
0455:             *            The encoding of the file to be archived.
0456:             * @param destinationEncoding
0457:             *            The encoding of the archived file.
0458:             * @param deleteSource
0459:             *            Flag if source should be deleted.
0460:             * @param forceArchive
0461:             *            Flag if we should archive even if file is already in the
0462:             *            archive directory.
0463:             * 
0464:             * @return The name of the archived file.
0465:             * 
0466:             * @throws IOException
0467:             */
0468:            public static String dumpArchive(File file, Filename root,
0469:                    String relativePath, int max, String sourceEncoding,
0470:                    String destinationEncoding, boolean deleteSource,
0471:                    boolean forceArchive) throws IOException {
0472:                if ((max == 0) || (root == null) || root.isNull()) {
0473:                    // no archiving desired
0474:                    return null;
0475:                }
0476:
0477:                String dirName = root.getDescendent(relativePath)
0478:                        .getFilenameAbsolute();
0479:                File archive;
0480:                if (!forceArchive
0481:                        && dirName.equals(file.getParentFile()
0482:                                .getAbsolutePath())) {
0483:                    // i'm already in the temp directory, no need to copy
0484:                    archive = file;
0485:                } else {
0486:                    DumpDirectory d = DumpDirectory.get(dirName);
0487:                    archive = d.getDumpFile(file.getName(), max);
0488:                    if (deleteSource) {
0489:                        FileTools.renameFile(file, sourceEncoding, archive,
0490:                                destinationEncoding);
0491:                    } else {
0492:                        FileTools.copyFile(file, sourceEncoding, archive,
0493:                                destinationEncoding);
0494:                    }
0495:                }
0496:                try {
0497:                    archive.setLastModified(System.currentTimeMillis());
0498:                } catch (Exception ignore) {
0499:                    // getLog().logWarning(getLogPrefix() + " could not set modification
0500:                    // time for file " + renamedFile.getPath());
0501:                }
0502:                return archive.getAbsolutePath();
0503:            }
0504:
0505:            /**
0506:             * @see #dumpArchive(File, Filename, String, int, String, String, boolean,
0507:             *      boolean)
0508:             */
0509:            public static String dumpArchive(InputStream is, Filename root,
0510:                    String relativePath, int max, String sourceEncoding,
0511:                    String destinationEncoding, String name) throws IOException {
0512:                if ((max == 0) || (root == null) || root.isNull()) {
0513:                    // no archiving desired
0514:                    return null;
0515:                }
0516:
0517:                String dirName = root.getDescendent(relativePath)
0518:                        .getFilenameAbsolute();
0519:                DumpDirectory d = DumpDirectory.get(dirName);
0520:                File archive = d.getDumpFile(name, max);
0521:                FileOutputStream os = new FileOutputStream(archive);
0522:                try {
0523:                    StreamTools.copyStream(is, os);
0524:                } catch (Exception e) {
0525:                    throw new IOException("archiving failed (" + e.getMessage()
0526:                            + ")");
0527:                } finally {
0528:                    try {
0529:                        if (os != null) {
0530:                            os.close();
0531:                        }
0532:                    } catch (Exception ignore) {
0533:                        // ignore failure
0534:                    }
0535:                }
0536:                return archive.getAbsolutePath();
0537:            }
0538:
0539:            /**
0540:             * Create an empty file.
0541:             * 
0542:             * @param file
0543:             * @throws IOException
0544:             */
0545:            public static void emptyFile(File file) throws IOException {
0546:                FileOutputStream os = new FileOutputStream(file);
0547:                try {
0548:                    //
0549:                } finally {
0550:                    StreamTools.close(os);
0551:                }
0552:            }
0553:
0554:            /**
0555:             * <code>true</code> when the two files represent the same physical file
0556:             * in the file system.
0557:             * 
0558:             * @param source
0559:             *            The first file to be checked.
0560:             * @param destination
0561:             *            The second file to be checked.
0562:             * 
0563:             * @return <code>true</code> when the two files represent the same
0564:             *         physical file in the file system.
0565:             */
0566:            public static boolean fileTheSame(File source, File destination) {
0567:                try {
0568:                    if (System.getProperty("os.name").toLowerCase().startsWith(
0569:                            "win")) {
0570:                        return source.getCanonicalPath().equalsIgnoreCase(
0571:                                destination.getCanonicalPath());
0572:                    } else {
0573:                        return source.getCanonicalPath().equals(
0574:                                destination.getCanonicalPath());
0575:                    }
0576:                } catch (IOException e) {
0577:                    return false;
0578:                }
0579:            }
0580:
0581:            /**
0582:             * Create a file from the byte content.
0583:             * 
0584:             * @param file
0585:             *            The file to write/create
0586:             * @param text
0587:             *            The text to be written into the file.
0588:             * 
0589:             * @throws IOException
0590:             */
0591:            public static void fromBytes(File file, byte[] bytes)
0592:                    throws IOException {
0593:                // todo change name
0594:                FileOutputStream os = new FileOutputStream(file);
0595:                try {
0596:                    // write stream all at once
0597:                    os.write(bytes);
0598:                } finally {
0599:                    StreamTools.close(os);
0600:                }
0601:            }
0602:
0603:            /**
0604:             * Create a file from the string content.
0605:             * 
0606:             * @param file
0607:             *            The file to write/create
0608:             * @param text
0609:             *            The text to be written into the file.
0610:             * 
0611:             * @throws IOException
0612:             */
0613:            public static void fromString(File file, String text)
0614:                    throws IOException {
0615:                // todo change name
0616:                // todo support encoding
0617:                Writer writer = new FileWriter(file);
0618:                try {
0619:                    // write stream all at once
0620:                    writer.write(text);
0621:                } finally {
0622:                    writer.close();
0623:                }
0624:            }
0625:
0626:            /**
0627:             * Get the local name of the file in its directory without the extension.
0628:             * 
0629:             * @param file
0630:             *            The file whose base name is requested.
0631:             * 
0632:             * @return The local name of the file in its directory without the
0633:             *         extension.
0634:             */
0635:            public static String getBaseName(File file) {
0636:                if (file == null) {
0637:                    return getBaseName((String) null, StringTools.EMPTY);
0638:                } else {
0639:                    return getBaseName(file.getName(), StringTools.EMPTY);
0640:                }
0641:            }
0642:
0643:            /**
0644:             * Get the local name of the file in its directory without the extension.
0645:             * 
0646:             * @param file
0647:             *            The file whose base name is requested.
0648:             * 
0649:             * @return The local name of the file in its directory without the
0650:             *         extension.
0651:             */
0652:            public static String getBaseName(File file, String defaultName) {
0653:                if (file == null) {
0654:                    return getBaseName((String) null, defaultName);
0655:                } else {
0656:                    return getBaseName(file.getName(), defaultName);
0657:                }
0658:            }
0659:
0660:            /**
0661:             * Get the local name of the file in its directory without the extension.
0662:             * 
0663:             * @param filename
0664:             *            The filename whose base name is requested.
0665:             * 
0666:             * @return The local name of the file in its directory without the
0667:             *         extension.
0668:             */
0669:            public static String getBaseName(String filename) {
0670:                return getBaseName(filename, StringTools.EMPTY);
0671:            }
0672:
0673:            /**
0674:             * Get the local name of the file in its directory without the extension.
0675:             * 
0676:             * @param filename
0677:             *            The filename whose base name is requested.
0678:             * @param defaultName
0679:             *            returned if filename is null or a empty String
0680:             * 
0681:             * @return The local name of the file in its directory without the
0682:             *         extension.
0683:             */
0684:            public static String getBaseName(String filename, String defaultName) {
0685:                if (StringTools.isEmpty(filename)) {
0686:                    return defaultName;
0687:                }
0688:                int dotPos = filename.lastIndexOf('.');
0689:                if (dotPos >= 1) {
0690:                    return filename.substring(0, dotPos);
0691:                }
0692:                return filename;
0693:            }
0694:
0695:            /**
0696:             * Get the extension of the file name. If no extension is present, the empty
0697:             * string is returned.
0698:             * 
0699:             * @param file
0700:             *            The file whose extension is requested.
0701:             * 
0702:             * @return The extension of the file name. If no extension is present, the
0703:             *         empty string is returned.
0704:             */
0705:            public static String getExtension(File file) {
0706:                return getExtension(file.getName());
0707:            }
0708:
0709:            /**
0710:             * Get the extension of the file name. If no extension is present, the empty
0711:             * string is returned.
0712:             * 
0713:             * @param filename
0714:             *            The filename whose extension is requested.
0715:             * 
0716:             * @return The extension of the file name. If no extension is present, the
0717:             *         empty string is returned.
0718:             */
0719:            public static String getExtension(String filename) {
0720:                return getExtension(filename, StringTools.EMPTY);
0721:            }
0722:
0723:            /**
0724:             * Get the extension of the file name. If no extension is present, the
0725:             * defaultName is returned.
0726:             * 
0727:             * @param filename
0728:             *            The filename whose extension is requested.
0729:             * 
0730:             * @param defaultName
0731:             *            returned if the filename is empty or null or there is no
0732:             *            extension
0733:             * 
0734:             * @return The extension of the file name. If no extension is present, the
0735:             *         empty string is returned.
0736:             */
0737:            public static String getExtension(String filename,
0738:                    String defaultName) {
0739:                if (StringTools.isEmpty(filename)) {
0740:                    return defaultName;
0741:                }
0742:                int dotPos = filename.lastIndexOf('.');
0743:                if (dotPos >= 0) {
0744:                    return filename.substring(dotPos + 1);
0745:                }
0746:                return defaultName;
0747:            }
0748:
0749:            /**
0750:             * Return the list of all files in the directory specified by
0751:             * <code>path</code>.
0752:             * 
0753:             * @param path
0754:             *            The name of the directory to lookup.
0755:             * 
0756:             * @return The list of all files in the directory specified by
0757:             *         <code>path</code>.
0758:             */
0759:            public static List getFiles(String path) {
0760:                return getFiles(path, null);
0761:            }
0762:
0763:            /**
0764:             * Return the list of all files in the directory specified by
0765:             * <code>path</code> that match the pattern defined in
0766:             * <code>pattern</code>.
0767:             * 
0768:             * @param path
0769:             *            The name of the directory to lookup.
0770:             * @param pattern
0771:             *            The pattern that should be matched.
0772:             * 
0773:             * @return the list of all files in the directory specified by
0774:             *         <code>path</code> that match the pattern defined in
0775:             *         <code>pattern</code>.
0776:             */
0777:            public static List getFiles(String path, String pattern) {
0778:                // todo handle relative file names.
0779:                List result = new ArrayList();
0780:                WildcardMatch test = new WildcardMatch();
0781:                File file = new File(path);
0782:
0783:                if (pattern == null) {
0784:                    pattern = "*";
0785:                }
0786:
0787:                if (file.isFile() == true) {
0788:                    Filename tmp = new Filename(path);
0789:                    if (test.match(pattern, file.getName()) == true) {
0790:                        result.add(tmp);
0791:                    }
0792:                } else {
0793:                    String[] allFiles = file.list();
0794:                    if (allFiles != null) {
0795:                        for (int i = 0; i < allFiles.length; i++) {
0796:                            if (test.match(pattern, allFiles[i]) == true) {
0797:                                Filename tmp = new Filename(path
0798:                                        + File.separator + allFiles[i]);
0799:                                result.add(tmp);
0800:                            }
0801:                        }
0802:                    }
0803:                }
0804:                return result;
0805:            }
0806:
0807:            /**
0808:             * Return <code>segment</code> as a path that is interpreted relative to
0809:             * <code>root</code> if it specifies a relative address, or a correct
0810:             * absolute path.
0811:             * 
0812:             * @param root
0813:             *            The optional parent of <code>segment</code>.
0814:             * @param segment
0815:             *            The adress whose adress relative to <code>root</code> is
0816:             *            requested.
0817:             * 
0818:             * @return <code>segment</code> as a path that is interpreted relative to
0819:             *         <code>root</code> if it specifies a relative address, or a
0820:             *         correct absolute path.
0821:             */
0822:            public static String getPathRelative(String root, String segment) {
0823:                if (StringTools.isEmpty(segment)) {
0824:                    return (root == null) ? StringTools.EMPTY : root;
0825:                }
0826:                if (StringTools.isEmpty(root)) {
0827:                    return segment;
0828:                }
0829:
0830:                File file = new File(segment);
0831:                if (file.isAbsolute()) {
0832:                    return segment;
0833:                }
0834:                File parent = new File(root);
0835:                if ((segment.charAt(0) == '/') || (segment.charAt(0) == '\\')) {
0836:                    // windows platform special; segment is interpreted relative to
0837:                    // drive
0838:                    return (new File(getRootName(parent), segment))
0839:                            .getAbsolutePath();
0840:                }
0841:
0842:                // segment is relative to directory
0843:                return (new File(parent, segment)).getAbsolutePath();
0844:            }
0845:
0846:            public static String getRelativePath(File sourceFolder, File target)
0847:                    throws IOException {
0848:                return RelativePath.getRelativePath(sourceFolder, target);
0849:            }
0850:
0851:            /**
0852:             * Get the file system root of the file.
0853:             * 
0854:             * <p>
0855:             * The root is defined here as a drive or UNC path specification.
0856:             * </p>
0857:             * 
0858:             * @param file
0859:             *            The file whose root is requested.
0860:             * 
0861:             * @return The file system root of the file.
0862:             */
0863:            public static String getRootName(File file) {
0864:                String path = file.getPath();
0865:                if (path.length() < 2) {
0866:                    return StringTools.EMPTY;
0867:                }
0868:                if (path.charAt(1) == ':') {
0869:                    return path.substring(0, 2);
0870:                }
0871:                if ((path.charAt(0) == '\\') && (path.charAt(1) == '\\')) {
0872:                    return path.substring(0, path.indexOf('\\', 2));
0873:                }
0874:                return StringTools.EMPTY;
0875:            }
0876:
0877:            public static String getWindowsStylePath(String osIndependentPath) {
0878:                String windows = osIndependentPath.replaceAll("/", "\\\\");
0879:                if (windows.startsWith("\\")) {
0880:                    if (!windows.startsWith("\\\\")) {
0881:                        windows = windows.substring(1);
0882:                        int index = windows.indexOf("\\");
0883:                        if (index < 0) {
0884:                            index = windows.length();
0885:                        }
0886:                        windows = windows.substring(0, index) + ":"
0887:                                + windows.substring(index);
0888:                    }
0889:                }
0890:                return windows;
0891:            }
0892:
0893:            /**
0894:             * The first index of <code>searchstring</code> within <code>file</code>.
0895:             * 
0896:             * <p>
0897:             * Use with care!
0898:             * </p>
0899:             * 
0900:             * @param file
0901:             *            The file where we search the string.
0902:             * @param searchstring
0903:             *            The string to be searched.
0904:             * 
0905:             * @return The first index of <code>searchstring</code> within
0906:             *         <code>file</code>.
0907:             * 
0908:             * @throws IOException
0909:             */
0910:            public static long indexOf(File file, String searchstring)
0911:                    throws IOException {
0912:                // todo this is ugly
0913:                // todo encoding
0914:                InputStream stream = null;
0915:                String string = null;
0916:                try {
0917:                    stream = new FileInputStream(file);
0918:
0919:                    byte[] content = new byte[stream.available()];
0920:                    stream.read(content, 0, stream.available());
0921:                    string = new String(content);
0922:                } finally {
0923:                    if (stream != null) {
0924:                        stream.close();
0925:                    }
0926:                }
0927:                return string.indexOf(searchstring);
0928:            }
0929:
0930:            /**
0931:             * Return a list of all lines in <code>file</code> that contain
0932:             * <code>searchstring</code>. The lines returned contain every character
0933:             * of the line remaining after the end of the occurence of
0934:             * <code>searchstring</code>.
0935:             * 
0936:             * <p>
0937:             * Use with care!
0938:             * </p>
0939:             * 
0940:             * @param file
0941:             *            The file where we search in.
0942:             * @param searchstring
0943:             *            The string to be searched.
0944:             * 
0945:             * @return A list of all lines in <code>file</code> that contain
0946:             *         <code>searchstring</code>.
0947:             * 
0948:             * @throws IOException
0949:             */
0950:            public static List linesContaining(File file, String searchstring)
0951:                    throws IOException {
0952:                // todo encoding
0953:                // todo ugly implementation
0954:                InputStream stream = null;
0955:                String string = null;
0956:                List list = new ArrayList();
0957:
0958:                try {
0959:                    stream = new FileInputStream(file);
0960:
0961:                    byte[] content = new byte[stream.available()];
0962:
0963:                    // read stream all at once
0964:                    stream.read(content, 0, stream.available());
0965:                    string = new String(content);
0966:                    for (int i = 0; i < string.length();) {
0967:                        int pos = string.indexOf(searchstring, i);
0968:                        if (pos == -1) {
0969:                            break;
0970:                        }
0971:
0972:                        int start = pos + searchstring.length();
0973:                        int stop = string.indexOf(System
0974:                                .getProperty("line.separator"), start);
0975:                        if (stop == -1) {
0976:                            stop = string.length();
0977:                        }
0978:                        list.add(string.substring(start, stop));
0979:                        i = stop + 1;
0980:                    }
0981:                } finally {
0982:                    if (stream != null) {
0983:                        stream.close();
0984:                    }
0985:                }
0986:                return list;
0987:            }
0988:
0989:            /**
0990:             * Append <code>text</code> to the file <code>destination</code>.
0991:             * 
0992:             * @param destination
0993:             *            The destination file.
0994:             * @param text
0995:             *            The text to be appended.
0996:             * 
0997:             * @throws IOException
0998:             */
0999:            public static void logToFile(File destination, String text)
1000:                    throws IOException {
1001:                // todo change name
1002:                FileOutputStream os = null;
1003:                try {
1004:                    byte[] b = text.getBytes();
1005:                    os = new FileOutputStream(destination.getAbsolutePath(),
1006:                            true);
1007:                    os.write(b, 0, b.length);
1008:                } catch (Exception e) {
1009:                    throw new IOException("logToFile failed (" + e.getMessage()
1010:                            + ")");
1011:                } finally {
1012:                    try {
1013:                        if (os != null) {
1014:                            os.close();
1015:                        }
1016:                    } catch (Exception ignore) {
1017:                        // ignore failure
1018:                    }
1019:                }
1020:            }
1021:
1022:            /**
1023:             * @see #renameFile(File, String, File, String)
1024:             */
1025:            public static void renameFile(File source, File destination)
1026:                    throws IOException {
1027:                renameFile(source, null, destination, null);
1028:            }
1029:
1030:            /**
1031:             * "Rename" a file.
1032:             * 
1033:             * <p>
1034:             * The effect is that there is a new file <code>destination</code>,
1035:             * encoded in <code>destinationEncoding</code>, the old file
1036:             * <code>source</code> is deleted.
1037:             * </p>
1038:             * 
1039:             * @param source
1040:             *            The source name of the file.
1041:             * @param sourceEncoding
1042:             *            The encoding of the source file.
1043:             * @param destination
1044:             *            The destination name of the file.
1045:             * @param destinationEncoding
1046:             *            The encoding of the destination file.
1047:             * 
1048:             * @throws IOException
1049:             *             docme
1050:             */
1051:            public static void renameFile(File source, String sourceEncoding,
1052:                    File destination, String destinationEncoding)
1053:                    throws IOException {
1054:                if (source.getCanonicalFile().equals(
1055:                        destination.getCanonicalFile())) {
1056:                    return;
1057:                }
1058:                if (((sourceEncoding != null) && (destinationEncoding != null) && !sourceEncoding
1059:                        .equals(destinationEncoding))
1060:                        || !source.renameTo(destination)) {
1061:                    // try a little harder
1062:                    // some implementations can't rename over different file system
1063:                    // platforms
1064:                    // (e.g. from NT to OS/2)
1065:                    copyFile(source, sourceEncoding, destination,
1066:                            destinationEncoding);
1067:                    if (!source.delete()) {
1068:                        // undo creation of copy
1069:                        destination.delete();
1070:                        throw new IOException("deleting " + source + " failed");
1071:                    }
1072:                }
1073:            }
1074:
1075:            /**
1076:             * Create a byte array with the files content.
1077:             * 
1078:             * @param file
1079:             *            The file to read.
1080:             * 
1081:             * @return Create a byte array with the files content.
1082:             * 
1083:             * @throws IOException
1084:             */
1085:            public static byte[] toBytes(File file) throws IOException {
1086:                InputStream is = null;
1087:                try {
1088:                    is = new FileInputStream(file);
1089:                    return StreamTools.toByteArray(is);
1090:                } finally {
1091:                    if (is != null) {
1092:                        is.close();
1093:                    }
1094:                }
1095:            }
1096:
1097:            public static String toOSIndependentPath(String osPath) {
1098:                String unix = osPath.replaceAll("\\\\", "/");
1099:                int index = unix.indexOf(":");
1100:                if ((index >= 0) && (index < unix.indexOf("/"))) {
1101:                    unix = "/" + unix.substring(0, index)
1102:                            + unix.substring(index + 1);
1103:                }
1104:                return unix;
1105:            }
1106:
1107:            public static String toOSPath(String osIndependentPath) {
1108:                if (File.separatorChar == '/') {
1109:                    return osIndependentPath;
1110:                }
1111:                String windows = osIndependentPath.replaceAll("/", "\\\\");
1112:                if (windows.startsWith("\\")) {
1113:                    if (!windows.startsWith("\\\\")) {
1114:                        windows = windows.substring(1);
1115:                        int index = windows.indexOf("\\");
1116:                        if (index < 0) {
1117:                            index = windows.length();
1118:                        }
1119:                        windows = windows.substring(0, index) + ":"
1120:                                + windows.substring(index);
1121:                    }
1122:                }
1123:                return windows;
1124:            }
1125:
1126:            /**
1127:             * Read a file's content at once and return as a string.
1128:             * 
1129:             * <p>
1130:             * Use with care!
1131:             * </p>
1132:             * 
1133:             * @param file
1134:             *            The file to read.
1135:             * 
1136:             * @return The string content of the file.
1137:             * 
1138:             * @throws IOException
1139:             */
1140:            public static String toString(File file) throws IOException {
1141:                return toString(file, System.getProperty("file.encoding"));
1142:            }
1143:
1144:            /**
1145:             * Read a file's content at once and return as a string in the correct
1146:             * encoding.
1147:             * 
1148:             * <p>
1149:             * Use with care!
1150:             * </p>
1151:             * 
1152:             * @param file
1153:             *            The file to read.
1154:             * @param encoding
1155:             *            The encoding to use.
1156:             * 
1157:             * @return The string content of the file.
1158:             * 
1159:             * @throws IOException
1160:             */
1161:            public static String toString(File file, String encoding)
1162:                    throws IOException {
1163:                InputStream is = null;
1164:                try {
1165:                    is = new FileInputStream(file);
1166:                    return StreamTools.toString(is, encoding);
1167:                } finally {
1168:                    if (is != null) {
1169:                        is.close();
1170:                    }
1171:                }
1172:            }
1173:
1174:            /**
1175:             * Wait for a file to arrive.
1176:             * 
1177:             * <p>
1178:             * The method waits at most <code>timeout</code> milliseconds for a file
1179:             * to arrive. When <code>delay</code> is != 0 the method checks the file's
1180:             * size for changes it reaches a stable size.
1181:             * </p>
1182:             * 
1183:             * @param file
1184:             *            The file to wait for.
1185:             * @param timeout
1186:             *            The maximum time in milliseconds to wait for first occurence
1187:             *            of <code>file</code>.
1188:             * @param delay
1189:             *            The number of milliseconds between two checks against the
1190:             *            files size.
1191:             * 
1192:             * @throws IOException
1193:             */
1194:            public static void wait(File file, long timeout, long delay)
1195:                    throws IOException {
1196:                // todo zero length files
1197:                long stop = System.currentTimeMillis() + timeout;
1198:                for (;;) {
1199:                    try {
1200:                        if (file.exists()) {
1201:                            if (delay > 0) {
1202:                                long oldSize = -1;
1203:                                long newSize = file.length();
1204:                                for (;;) {
1205:                                    if (oldSize != newSize) {
1206:                                        oldSize = newSize;
1207:                                        Thread.sleep(delay);
1208:                                        newSize = file.length();
1209:                                        continue;
1210:                                    }
1211:                                    break;
1212:                                }
1213:                            }
1214:                            return;
1215:                        }
1216:                        if (System.currentTimeMillis() > stop) {
1217:                            // timeout
1218:                            throw new IOException("timeout waiting for "
1219:                                    + file.getPath());
1220:                        }
1221:                        Thread.sleep(1000);
1222:                    } catch (InterruptedException e) {
1223:                        // interrupted
1224:                        throw new IOException("interrupted waiting for "
1225:                                + file.getPath());
1226:                    }
1227:                }
1228:            }
1229:
1230:            static final String[] hex = { "%00", "%01", "%02", "%03", "%04",
1231:                    "%05", "%06", "%07", "%08", "%09", "%0a", "%0b", "%0c",
1232:                    "%0d", "%0e", "%0f", "%10", "%11", "%12", "%13", "%14",
1233:                    "%15", "%16", "%17", "%18", "%19", "%1a", "%1b", "%1c",
1234:                    "%1d", "%1e", "%1f", "%20", "%21", "%22", "%23", "%24",
1235:                    "%25", "%26", "%27", "%28", "%29", "%2a", "%2b", "%2c",
1236:                    "%2d", "%2e", "%2f", "%30", "%31", "%32", "%33", "%34",
1237:                    "%35", "%36", "%37", "%38", "%39", "%3a", "%3b", "%3c",
1238:                    "%3d", "%3e", "%3f", "%40", "%41", "%42", "%43", "%44",
1239:                    "%45", "%46", "%47", "%48", "%49", "%4a", "%4b", "%4c",
1240:                    "%4d", "%4e", "%4f", "%50", "%51", "%52", "%53", "%54",
1241:                    "%55", "%56", "%57", "%58", "%59", "%5a", "%5b", "%5c",
1242:                    "%5d", "%5e", "%5f", "%60", "%61", "%62", "%63", "%64",
1243:                    "%65", "%66", "%67", "%68", "%69", "%6a", "%6b", "%6c",
1244:                    "%6d", "%6e", "%6f", "%70", "%71", "%72", "%73", "%74",
1245:                    "%75", "%76", "%77", "%78", "%79", "%7a", "%7b", "%7c",
1246:                    "%7d", "%7e", "%7f", "%80", "%81", "%82", "%83", "%84",
1247:                    "%85", "%86", "%87", "%88", "%89", "%8a", "%8b", "%8c",
1248:                    "%8d", "%8e", "%8f", "%90", "%91", "%92", "%93", "%94",
1249:                    "%95", "%96", "%97", "%98", "%99", "%9a", "%9b", "%9c",
1250:                    "%9d", "%9e", "%9f", "%a0", "%a1", "%a2", "%a3", "%a4",
1251:                    "%a5", "%a6", "%a7", "%a8", "%a9", "%aa", "%ab", "%ac",
1252:                    "%ad", "%ae", "%af", "%b0", "%b1", "%b2", "%b3", "%b4",
1253:                    "%b5", "%b6", "%b7", "%b8", "%b9", "%ba", "%bb", "%bc",
1254:                    "%bd", "%be", "%bf", "%c0", "%c1", "%c2", "%c3", "%c4",
1255:                    "%c5", "%c6", "%c7", "%c8", "%c9", "%ca", "%cb", "%cc",
1256:                    "%cd", "%ce", "%cf", "%d0", "%d1", "%d2", "%d3", "%d4",
1257:                    "%d5", "%d6", "%d7", "%d8", "%d9", "%da", "%db", "%dc",
1258:                    "%dd", "%de", "%df", "%e0", "%e1", "%e2", "%e3", "%e4",
1259:                    "%e5", "%e6", "%e7", "%e8", "%e9", "%ea", "%eb", "%ec",
1260:                    "%ed", "%ee", "%ef", "%f0", "%f1", "%f2", "%f3", "%f4",
1261:                    "%f5", "%f6", "%f7", "%f8", "%f9", "%fa", "%fb", "%fc",
1262:                    "%fd", "%fe", "%ff" };
1263:
1264:            private FileTools() {
1265:                //
1266:            }
1267:
1268:            /**
1269:             * Try to get a valid parent for file.
1270:             * 
1271:             * @param file
1272:             */
1273:            public static File getParentFile(File file) {
1274:                File parentFile = file.getParentFile();
1275:                if (parentFile == null) {
1276:                    parentFile = file.getAbsoluteFile().getParentFile();
1277:                }
1278:                if (parentFile == null) {
1279:                    return null;
1280:                }
1281:                File grandpa = parentFile.getParentFile();
1282:                if (grandpa != null) {
1283:                    // filter UNC path root also
1284:                    String grandpaPath = grandpa.getAbsolutePath();
1285:                    if ((grandpaPath.length() == 2)
1286:                            && (grandpaPath.charAt(1) == File.separatorChar)) {
1287:                        return null;
1288:                    }
1289:                }
1290:                return parentFile;
1291:            }
1292:
1293:            /**
1294:             * @param param
1295:             *            java.lang.String Trims and replaces all characters which are
1296:             *            not allowed in filenames (for Win32) with spaces
1297:             * 
1298:             * @return java.lang.String
1299:             */
1300:            public static String trimToFileConform(String param) {
1301:                return trimToFileConform(param, null);
1302:            }
1303:
1304:            private static final char FILE_OK_CHAR = '_';
1305:
1306:            /**
1307:             * docme
1308:             * 
1309:             * @param param
1310:             *            docme
1311:             * @param protectedChars
1312:             *            docme
1313:             * 
1314:             * @return docme
1315:             */
1316:            public static String trimToFileConform(String param,
1317:                    String protectedChars) {
1318:                if (param == null) {
1319:                    return null;
1320:                }
1321:                String replaceChars = "\n\t\b\f\r\"*?<>|:";
1322:                replaceChars = FileTools.replaceAllChars(replaceChars,
1323:                        protectedChars, FILE_OK_CHAR);
1324:                String tmp = param.trim();
1325:
1326:                // make for uniform use of slash and backslash
1327:                tmp = tmp.replace('\\', File.separatorChar);
1328:                tmp = tmp.replace('/', File.separatorChar);
1329:                String drivePrefix = StringTools.EMPTY;
1330:                if ((tmp.length() > 2) && (tmp.charAt(1) == ':')) {
1331:                    drivePrefix = tmp.substring(0, 2);
1332:                    tmp = tmp.substring(2);
1333:                }
1334:                tmp = FileTools
1335:                        .replaceAllChars(tmp, replaceChars, FILE_OK_CHAR);
1336:                return drivePrefix + tmp;
1337:            }
1338:
1339:            /**
1340:             * docme
1341:             * 
1342:             * @param param
1343:             *            docme
1344:             * 
1345:             * @return docme
1346:             */
1347:            public static String trimToURLConform(String param) {
1348:                URL url;
1349:                if (param == null) {
1350:                    return null;
1351:                }
1352:
1353:                // don't be to stringent with slashes
1354:                param = param.trim().replace('\\', '/');
1355:                try {
1356:                    url = new URL(param);
1357:                } catch (Exception e) {
1358:                    return null;
1359:                }
1360:                boolean isFileURL = url.getProtocol().equalsIgnoreCase("file");
1361:
1362:                // new URL(String) cuts all leading '/' of file except the first
1363:                // --> UNC paths are not recognizable
1364:                // therefore UNC paths are detected here
1365:                // file:///// is UNC
1366:                // file://// is not
1367:                boolean isUNC = (url.getProtocol().equalsIgnoreCase("file") && param
1368:                        .startsWith("//", 8));
1369:
1370:                String host = url.getHost();
1371:                host = urlPathEscapeEncodeHTTP(host);
1372:                String file = url.getFile();
1373:                if (file == null) {
1374:                    return null;
1375:                }
1376:                if (file.startsWith("/")) {
1377:                    file = file.substring(1);
1378:                }
1379:                String path = file;
1380:
1381:                String query = StringTools.EMPTY;
1382:                int index = file.indexOf('?');
1383:                if (index != -1) {
1384:                    path = file.substring(0, index);
1385:                    query = file.substring(index + 1);
1386:                }
1387:
1388:                path = FileTools.trimToFileConform(path);
1389:                // for relative path (?)
1390:                if ((path.length() > 0)
1391:                        && (path.charAt(0) != File.separatorChar)) {
1392:                    path = File.separatorChar + path;
1393:                }
1394:
1395:                // fill up to file URL to get file:///c:/...
1396:                if (isFileURL) {
1397:                    path = "//" + path;
1398:                }
1399:
1400:                // fill up to file URL to get file://///ws15/...
1401:                // for VA's VM one had to add '//' to get the correct URL
1402:                // but for JRE 1.3.1 it works only this way
1403:                // todo url handling for files. unit tests
1404:                if (isUNC) {
1405:                    path = "/" + path;
1406:                }
1407:                path = path.replace('\\', '/');
1408:                if (isFileURL) {
1409:                    path = urlPathEscapeEncodeFILE(path);
1410:                } else {
1411:                    path = urlPathEscapeEncodeHTTP(path);
1412:                }
1413:
1414:                // treating of queries starting with '?'
1415:                query = urlQueryFormEncode(query);
1416:                if (query.length() > 0) {
1417:                    file = path + "?" + query;
1418:                } else {
1419:                    file = path;
1420:                }
1421:
1422:                // treating of parameters sequences starting with '#'
1423:                // known use case is with Acrobat plugin for IE: url#FDF=url
1424:                // todo treat # part recursively with this method? only after skipping
1425:                // characters FDF=, are there others?
1426:                // todo what happens when ? and # occurs?
1427:                // do not add it to the file again because '#' would be replaced in
1428:                // urlPathEscapeEncode()
1429:                String pluginParameter = StringTools.EMPTY;
1430:
1431:                // with '#' starting parameter sequence is not part of file!
1432:                index = url.toString().indexOf('#');
1433:                if (index != -1) {
1434:                    pluginParameter = url.toString().substring(index + 1);
1435:                }
1436:                pluginParameter = pluginParameter.replace('\\', '/');
1437:                if (isFileURL) {
1438:                    pluginParameter = urlPathEscapeEncodeFILE(pluginParameter);
1439:                } else {
1440:                    pluginParameter = urlPathEscapeEncodeHTTP(pluginParameter);
1441:                }
1442:                if (pluginParameter.length() > 0) {
1443:                    file = file + "#" + pluginParameter;
1444:                }
1445:
1446:                try {
1447:                    return (new URL(url.getProtocol(), host, url.getPort(),
1448:                            file)).toString();
1449:                } catch (Exception e) {
1450:                    return null;
1451:                }
1452:            }
1453:
1454:            /**
1455:             * DOCUMENT ME!
1456:             * 
1457:             * @param s
1458:             *            The string to be encoded
1459:             * 
1460:             * @return The encoded string
1461:             */
1462:            public static String urlPathEscapeEncodeFILE(String s) {
1463:                StringBuilder sbuf = new StringBuilder();
1464:                int len = s.length();
1465:                for (int i = 0; i < len; i++) {
1466:                    int ch = s.charAt(i);
1467:                    if (ch == '<') {
1468:                        sbuf.append(hex[ch]);
1469:                    } else if (ch == '>') {
1470:                        sbuf.append(hex[ch]);
1471:                    } else if (ch == '"') {
1472:                        sbuf.append(hex[ch]);
1473:                    } else if (ch <= 0x001f) {
1474:                        sbuf.append(hex[ch]);
1475:                    } else if ((ch > 0x00FF) && (ch <= 0x07FF)) { // non-ASCII <=
1476:                        // 0x7FF
1477:                        sbuf.append(hex[0xc0 | (ch >> 6)]);
1478:                        sbuf.append(hex[0x80 | (ch & 0x3F)]);
1479:                    } else if (ch > 0x07FF) { // 0x7FF < ch <= 0xFFFF
1480:                        sbuf.append(hex[0xe0 | (ch >> 12)]);
1481:                        sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]);
1482:                        sbuf.append(hex[0x80 | (ch & 0x3F)]);
1483:                    } else {
1484:                        sbuf.append((char) ch);
1485:                    }
1486:                }
1487:                return sbuf.toString();
1488:            }
1489:
1490:            /**
1491:             * DOCUMENT ME!
1492:             * 
1493:             * @param s
1494:             *            The string to be encoded
1495:             * 
1496:             * @return The encoded string
1497:             */
1498:            public static String urlPathEscapeEncodeHTTP(String s) {
1499:                StringBuilder sbuf = new StringBuilder();
1500:                int len = s.length();
1501:                for (int i = 0; i < len; i++) {
1502:                    int ch = s.charAt(i);
1503:                    if (ch == ' ') {
1504:                        sbuf.append(hex[ch]);
1505:                    } else if (ch == '<') {
1506:                        sbuf.append(hex[ch]);
1507:                    } else if (ch == '>') {
1508:                        sbuf.append(hex[ch]);
1509:                    } else if (ch == '"') {
1510:                        sbuf.append(hex[ch]);
1511:                    } else if (ch == '#') {
1512:                        sbuf.append(hex[ch]);
1513:                    } else if (ch == '%') {
1514:                        sbuf.append(hex[ch]);
1515:                    } else if (ch == '\u20AC') { // EURO SIGN
1516:                        sbuf.append(hex[128]);
1517:                    } else if (ch <= 0x001f) {
1518:                        sbuf.append(hex[ch]);
1519:                    } else if ((ch > 0x00A0) && (ch <= 0x00FF)) { // ASCII / special
1520:                        // chars
1521:                        sbuf.append(hex[ch]);
1522:                    } else if ((ch > 0x00FF) && (ch <= 0x07FF)) { // non-ASCII <=
1523:                        // 0x7FF
1524:                        sbuf.append(hex[0xc0 | (ch >> 6)]);
1525:                        sbuf.append(hex[0x80 | (ch & 0x3F)]);
1526:                    } else if (ch > 0x07FF) { // 0x7FF < ch <= 0xFFFF
1527:                        sbuf.append(hex[0xe0 | (ch >> 12)]);
1528:                        sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]);
1529:                        sbuf.append(hex[0x80 | (ch & 0x3F)]);
1530:                    } else {
1531:                        sbuf.append((char) ch);
1532:                    }
1533:                }
1534:                return sbuf.toString();
1535:            }
1536:
1537:            /**
1538:             * Encode a string to the "x-www-form-urlencoded" form, enhanced with the
1539:             * UTF-8-in-URL proposal. This is what happens:
1540:             * 
1541:             * <ul>
1542:             * <li>
1543:             * <p>
1544:             * The ASCII characters 'a' through 'z', 'A' through 'Z', and '0' through
1545:             * '9' remain the same.
1546:             * </p>
1547:             * </li>
1548:             * <li>
1549:             * <p>
1550:             * The space character ' ' is converted into a plus sign '+'.
1551:             * </p>
1552:             * </li>
1553:             * <li>
1554:             * <p>
1555:             * All other ASCII characters are converted into the 3-character string
1556:             * "%xy", where xy is the two-digit hexadecimal representation of the
1557:             * character code
1558:             * </p>
1559:             * </li>
1560:             * <li>
1561:             * <p>
1562:             * All non-ASCII characters are encoded in two steps: first to a sequence of
1563:             * 2 or 3 bytes, using the UTF-8 algorithm; secondly each of these bytes is
1564:             * encoded as "%xx".
1565:             * </p>
1566:             * </li>
1567:             * </ul>
1568:             * 
1569:             * 
1570:             * @param s
1571:             *            The string to be encoded
1572:             * 
1573:             * @return The encoded string
1574:             */
1575:            public static String urlQueryFormEncode(String s) {
1576:                StringBuilder sbuf = new StringBuilder();
1577:                int len = s.length();
1578:                for (int i = 0; i < len; i++) {
1579:                    int ch = s.charAt(i);
1580:                    if (('A' <= ch) && (ch <= 'Z')) { // 'A'..'Z'
1581:                        sbuf.append((char) ch);
1582:                    } else if (('a' <= ch) && (ch <= 'z')) { // 'a'..'z'
1583:                        sbuf.append((char) ch);
1584:                    } else if (('0' <= ch) && (ch <= '9')) { // '0'..'9'
1585:                        sbuf.append((char) ch);
1586:                    } else if (ch == ' ') { // space
1587:                        sbuf.append('+');
1588:                    } else if (ch <= 0x007f) { // other ASCII
1589:                        sbuf.append(hex[ch]);
1590:                    } else if (ch <= 0x07FF) { // non-ASCII <= 0x7FF
1591:                        sbuf.append(hex[0xc0 | (ch >> 6)]);
1592:                        sbuf.append(hex[0x80 | (ch & 0x3F)]);
1593:                    } else { // 0x7FF < ch <= 0xFFFF
1594:                        sbuf.append(hex[0xe0 | (ch >> 12)]);
1595:                        sbuf.append(hex[0x80 | ((ch >> 6) & 0x3F)]);
1596:                        sbuf.append(hex[0x80 | (ch & 0x3F)]);
1597:                    }
1598:                }
1599:                return sbuf.toString();
1600:            }
1601:
1602:            /**
1603:             * docme
1604:             * 
1605:             * @param source
1606:             *            docme
1607:             * @param replace
1608:             *            docme
1609:             * @param with
1610:             *            docme
1611:             * 
1612:             * @return docme
1613:             */
1614:            public static String replaceAllChars(String source, String replace,
1615:                    char with) {
1616:                if ((source == null) || (replace == null)) {
1617:                    return source;
1618:                }
1619:                String result = source;
1620:                for (int i = 0; i < replace.length(); i++) {
1621:                    char newChar = replace.charAt(i);
1622:                    if (newChar != with) {
1623:                        result = result.replace(newChar, with);
1624:                    }
1625:                }
1626:                return result;
1627:            }
1628:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.