Source Code Cross Referenced for FileUtil.java in  » Scripting » jacl » tcl » lang » 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 » Scripting » jacl » tcl.lang 
Source Cross Referenced  Class Diagram Java Document (Java Doc) 


0001:        /*
0002:         * FileUtil.java --
0003:         *
0004:         *	This file contains utility methods for file-related operations.
0005:         *
0006:         * Copyright (c) 1997 Sun Microsystems, Inc.
0007:         *
0008:         * See the file "license.terms" for information on usage and
0009:         * redistribution of this file, and for a DISCLAIMER OF ALL
0010:         * WARRANTIES.
0011:         * 
0012:         * RCS: @(#) $Id: FileUtil.java,v 1.7 2005/11/07 07:41:51 mdejong Exp $
0013:         *
0014:         */
0015:
0016:        package tcl.lang;
0017:
0018:        import java.io.*;
0019:        import java.util.*;
0020:
0021:        /*
0022:         * This class implements utility methods for file-related operations.
0023:         */
0024:
0025:        class FileUtil {
0026:
0027:            static final int PATH_RELATIVE = 0;
0028:            static final int PATH_VOLUME_RELATIVE = 1;
0029:            static final int PATH_ABSOLUTE = 2;
0030:
0031:            /*
0032:             *-----------------------------------------------------------------------------
0033:             *
0034:             * getWinHomePath --
0035:             *
0036:             *	In the Windows file system, one type of absolute path follows this
0037:             *	regular expression:  ^(//+[a-zA-Z]+/+[a-zA-Z]+) 
0038:             *
0039:             *	If "path" doesn't fit the pattern, then return 0.
0040:             *	If the stopEarly bool is true, then return the index of the first
0041:             *	non-slash character in path, as soon as we know that path fits the
0042:             *	pattern.  Otherwise, return the index of the slash (or end of string) 
0043:             *	following the entire absolute path.
0044:             *
0045:             * Results:
0046:             *	Returns an integer index in path.
0047:             *
0048:             * Side effects:
0049:             *	If "path" fits the pattern, and "stopEarly" is not chosen, the absolute
0050:             *	path is coppied (without extra slashes) to "absBuf".  Otherwise, absBuf
0051:             *	is set to "".
0052:             *
0053:             *-----------------------------------------------------------------------------
0054:             */
0055:
0056:            private static int getWinHomePath(String path, // Path to compute home path of.
0057:                    boolean stopEarly, // Flag to skip side effect.
0058:                    StringBuffer absBuf) // Buffer to store side effect.
0059:            {
0060:                int pIndex, oldIndex, firstNonSlash;
0061:
0062:                // The first 2 or more chars must be slashes.
0063:
0064:                for (pIndex = 0; pIndex < path.length(); pIndex++) {
0065:                    if (path.charAt(pIndex) != '/') {
0066:                        break;
0067:                    }
0068:                }
0069:                if (pIndex < 2) {
0070:                    absBuf.setLength(0);
0071:                    return 0;
0072:                }
0073:                firstNonSlash = pIndex;
0074:
0075:                // The next 1 or more chars may not be slashes.
0076:
0077:                for (; pIndex < path.length(); pIndex++) {
0078:                    if (path.charAt(pIndex) == '/') {
0079:                        break;
0080:                    }
0081:                }
0082:                if (pIndex == firstNonSlash) {
0083:                    absBuf.setLength(0);
0084:                    return 0;
0085:                }
0086:                absBuf.ensureCapacity(absBuf.length() + path.length());
0087:                absBuf.append("//");
0088:                absBuf.append(path.substring(firstNonSlash, pIndex));
0089:
0090:                // The next 1 or more chars must be slashes.
0091:
0092:                oldIndex = pIndex;
0093:                for (; pIndex < path.length(); pIndex++) {
0094:                    if (path.charAt(pIndex) != '/') {
0095:                        if (pIndex == oldIndex) {
0096:                            absBuf.setLength(0);
0097:                            return 0;
0098:                        }
0099:
0100:                        // We know that the path fits the pattern.
0101:
0102:                        if (stopEarly) {
0103:                            absBuf.setLength(0);
0104:                            return firstNonSlash;
0105:                        }
0106:                        firstNonSlash = pIndex;
0107:
0108:                        // Traverse the path until a new slash (or end of string) is found.
0109:                        // Return the index of the new slash.
0110:
0111:                        pIndex++;
0112:                        for (; pIndex < path.length(); pIndex++) {
0113:                            if (path.charAt(pIndex) == '/') {
0114:                                break;
0115:                            }
0116:                        }
0117:                        absBuf.append('/');
0118:                        absBuf.append(path.substring(firstNonSlash, pIndex));
0119:                        return pIndex;
0120:                    }
0121:                }
0122:                absBuf.setLength(0);
0123:                return 0;
0124:            }
0125:
0126:            /*
0127:             *-----------------------------------------------------------------------------
0128:             *
0129:             * beginsWithLetterColon --
0130:             *
0131:             *	Determine whether a given windows path begins with [a-zA-Z]:
0132:             *	Return O if path doesn't begin with [a-zA-Z]:
0133:             *	Return 3 if path begins with [a-zA-Z]:/
0134:             *	Otherwise, return 2.
0135:             *
0136:             * Results:
0137:             *	Returns an integer.
0138:             *
0139:             * Side effects:
0140:             *	None.
0141:             *
0142:             *-----------------------------------------------------------------------------
0143:             */
0144:
0145:            private static int beginsWithLetterColon(String path) // Path to check start pattern.
0146:            {
0147:                if ((path.length() > 1) && (Character.isLetter(path.charAt(0)))
0148:                        && (path.charAt(1) == ':')) {
0149:
0150:                    int pIndex;
0151:                    for (pIndex = 2; pIndex < path.length(); pIndex++) {
0152:                        if (path.charAt(pIndex) != '/') {
0153:                            break;
0154:                        }
0155:                    }
0156:                    return pIndex;
0157:                }
0158:                return 0;
0159:            }
0160:
0161:            /*
0162:             *-----------------------------------------------------------------------------
0163:             *
0164:             * getWinAbsPath --
0165:             *
0166:             *	If "path" begins with [A-Z]: or '/', return the index of the character
0167:             *	(or end of string) following the absolute (or volume realtive) path.
0168:             *	Otherwise, return 0.
0169:             *
0170:             * Results:
0171:             *	Returns an integer index in path.
0172:             *
0173:             * Side effects:
0174:             *	If "path" begins with [A-Z]: or '/', copy the absolute (or volume
0175:             *	realtive) path up to the index returned into absBuf, removing extra
0176:             *	slashes. 
0177:             *
0178:             *-----------------------------------------------------------------------------
0179:             */
0180:
0181:            private static int getWinAbsPath(String path, // Path for which we find abs path.
0182:                    StringBuffer absBuf) // Buffer to store side effect.
0183:            {
0184:                absBuf.setLength(0);
0185:
0186:                if (path.length() < 1) {
0187:                    return 0;
0188:                }
0189:
0190:                absBuf.ensureCapacity(absBuf.length() + path.length());
0191:
0192:                int colonIndex = beginsWithLetterColon(path);
0193:                if (colonIndex > 0) {
0194:                    if (colonIndex > 2) {
0195:                        absBuf.append(path.substring(0, 3));
0196:                    } else {
0197:                        absBuf.append(path.substring(0, 2));
0198:                    }
0199:                    return colonIndex;
0200:                } else {
0201:                    int absIndex = getWinHomePath(path, false, absBuf);
0202:                    if (absIndex > 0) {
0203:                        return absIndex;
0204:                    } else if (path.charAt(0) == '/') {
0205:                        int pIndex;
0206:                        for (pIndex = 1; pIndex < path.length(); pIndex++) {
0207:                            if (path.charAt(pIndex) != '/') {
0208:                                break;
0209:                            }
0210:                        }
0211:                        absBuf.append("/");
0212:                        return pIndex;
0213:                    }
0214:                }
0215:                return 0;
0216:            }
0217:
0218:            /*
0219:             *-----------------------------------------------------------------------------
0220:             *
0221:             * getDegenerateUnixPath --
0222:             *
0223:             *	Returns the index of the 1st char (or end of string) which nolonger
0224:             *	follows the degenerate unix-style name pattern: 
0225:             *
0226:             *		^(/+([.][.]?/+)*([.][.]?)?)
0227:             *
0228:             * Results:
0229:             *	Returns an int index to "path".
0230:             *
0231:             * Side effects:
0232:             *	None.
0233:             *
0234:             *-----------------------------------------------------------------------------
0235:             */
0236:
0237:            private static int getDegenerateUnixPath(String path) // Path to check.
0238:            {
0239:                int pIndex = 0;
0240:
0241:                while ((pIndex < path.length()) && (path.charAt(pIndex) == '/')) {
0242:                    ++pIndex;
0243:                }
0244:
0245:                // "path" doesn't begin with a '/'.
0246:
0247:                if (pIndex == 0) {
0248:                    return 0;
0249:                }
0250:                while (pIndex < path.length()) {
0251:                    String tmpPath = path.substring(pIndex);
0252:                    if (tmpPath.startsWith("./")) {
0253:                        pIndex += 2;
0254:                    } else if (tmpPath.startsWith("../")) {
0255:                        pIndex += 3;
0256:                    } else {
0257:                        break;
0258:                    }
0259:                    while ((pIndex < path.length())
0260:                            && (path.charAt(pIndex) == '/')) {
0261:                        ++pIndex;
0262:                    }
0263:                }
0264:                if ((pIndex < path.length()) && (path.charAt(pIndex) == '.')) {
0265:                    ++pIndex;
0266:                }
0267:                if ((pIndex < path.length()) && (path.charAt(pIndex) == '.')) {
0268:                    ++pIndex;
0269:                }
0270:
0271:                // pIndex may be 1 past the end of "path".
0272:
0273:                return pIndex;
0274:            }
0275:
0276:            /*
0277:             *-----------------------------------------------------------------------------
0278:             *
0279:             * getPathType --
0280:             *
0281:             *	Determine whether "path" is absolute, volumerelative, or
0282:             *	relative.  It is necessary to perform system specific 
0283:             *	operations.
0284:             *
0285:             * Results:
0286:             *	Returns an integer value representing the path type.
0287:             *
0288:             * Side effects:
0289:             *	None.
0290:             *
0291:             *-----------------------------------------------------------------------------
0292:             */
0293:
0294:            static int getPathType(String path) // Path for which we find pathtype.
0295:            {
0296:                char c;
0297:                if (path.length() < 1) {
0298:                    return PATH_RELATIVE;
0299:                }
0300:
0301:                switch (JACL.PLATFORM) {
0302:                case JACL.PLATFORM_WINDOWS:
0303:                    path = path.replace('\\', '/');
0304:
0305:                    // Windows absolute pathes start with '~' or [a-zA-Z]:/ or home
0306:                    // path.
0307:
0308:                    c = path.charAt(0);
0309:                    if (c == '~') {
0310:                        return PATH_ABSOLUTE;
0311:                    }
0312:                    if (c == '/') {
0313:                        StringBuffer absBuf = new StringBuffer();
0314:                        if (getWinHomePath(path, true, absBuf) > 0) {
0315:                            return PATH_ABSOLUTE;
0316:                        }
0317:                        return PATH_VOLUME_RELATIVE;
0318:                    }
0319:                    int colonIndex = beginsWithLetterColon(path);
0320:                    if (colonIndex > 0) {
0321:                        if (colonIndex > 2) {
0322:                            return PATH_ABSOLUTE;
0323:                        }
0324:                        return PATH_VOLUME_RELATIVE;
0325:                    }
0326:                    return PATH_RELATIVE;
0327:
0328:                case JACL.PLATFORM_MAC:
0329:                    if (path.charAt(0) == '~') {
0330:                        return PATH_ABSOLUTE;
0331:                    }
0332:
0333:                    switch (path.indexOf(':')) {
0334:                    case -1:
0335:                        // Unix-style name contains no colons.  Return absolute iff "path"
0336:                        // begins with '/' and is not degenerate.  Otherwise, return
0337:                        // relative.
0338:
0339:                        if ((path.charAt(0) == '/')
0340:                                && (getDegenerateUnixPath(path) < path.length())) {
0341:                            return PATH_ABSOLUTE;
0342:                        }
0343:                        break;
0344:                    case 0:
0345:                        // Mac-style name contains a colon in the first position.
0346:
0347:                        return PATH_RELATIVE;
0348:                    default:
0349:                        // Mac-style name contains a colon, but not in the first position.
0350:
0351:                        return PATH_ABSOLUTE;
0352:                    }
0353:                    return PATH_RELATIVE;
0354:
0355:                default:
0356:                    // Unix absolute pathes start with either '/' or '~'.
0357:
0358:                    c = path.charAt(0);
0359:                    if ((c == '/') || (c == '~')) {
0360:                        return PATH_ABSOLUTE;
0361:                    }
0362:                }
0363:                return PATH_RELATIVE;
0364:            }
0365:
0366:            /*
0367:             *-----------------------------------------------------------------------------
0368:             *
0369:             * getNewFileObj --
0370:             *
0371:             *	Create a new File object with the name "fileName".
0372:             *
0373:             * Results:
0374:             *	Returns the newly created File object.
0375:             *
0376:             * Side effects:
0377:             *	None.
0378:             *
0379:             *-----------------------------------------------------------------------------
0380:             */
0381:
0382:            static File getNewFileObj(Interp interp, // Current interpreter.
0383:                    String fileName) // File to create object for.
0384:                    throws TclException {
0385:                final boolean debug = false;
0386:                fileName = translateFileName(interp, fileName);
0387:                if (debug) {
0388:                    System.out.println("File name is \"" + fileName + "\"");
0389:                }
0390:                switch (getPathType(fileName)) {
0391:                case PATH_RELATIVE:
0392:                    if (debug) {
0393:                        System.out.println("File name is PATH_RELATIVE");
0394:                    }
0395:                    return new File(interp.getWorkingDir(), fileName);
0396:                case PATH_VOLUME_RELATIVE:
0397:                    if (debug) {
0398:                        System.out.println("File name is PATH_VOLUME_RELATIVE");
0399:                    }
0400:
0401:                    // Something is very wrong if interp.getWorkingDir()
0402:                    // does not start with C: or another drive letter
0403:                    String cwd = interp.getWorkingDir().toString();
0404:                    int index = beginsWithLetterColon(cwd);
0405:                    if (index == 0) {
0406:                        throw new TclRuntimeError("interp working directory \""
0407:                                + cwd + "\" does not start with a drive letter");
0408:                    }
0409:
0410:                    // We can not use the joinPath() method because joing("D:/", "/f.txt")
0411:                    // returns "/f.txt" for some wacky reason. Just do it ourselves.
0412:                    StringBuffer buff = new StringBuffer();
0413:                    buff.append(cwd.substring(0, 2));
0414:                    buff.append('\\');
0415:                    for (int i = 0; i < fileName.length(); i++) {
0416:                        if (fileName.charAt(i) != '\\') {
0417:                            // Once we skip all the \ characters at the front
0418:                            // append the rest of the fileName onto the buffer
0419:                            buff.append(fileName.substring(i));
0420:                            break;
0421:                        }
0422:                    }
0423:
0424:                    fileName = buff.toString();
0425:
0426:                    if (debug) {
0427:                        System.out.println("After PATH_VOLUME_RELATIVE join \""
0428:                                + fileName + "\"");
0429:                    }
0430:
0431:                    return new File(fileName);
0432:                case PATH_ABSOLUTE:
0433:                    if (debug) {
0434:                        System.out.println("File name is PATH_ABSOLUTE");
0435:                    }
0436:                    return new File(fileName);
0437:                default:
0438:                    throw new TclRuntimeError("type for fileName \"" + fileName
0439:                            + "\" not matched in case statement");
0440:                }
0441:            }
0442:
0443:            /*
0444:             *-----------------------------------------------------------------------------
0445:             *
0446:             * appendComponent --
0447:             *
0448:             *	Append "component" to "buf" while eliminating extra slashes.
0449:             *
0450:             * Results:
0451:             *	None.
0452:             *
0453:             * Side effects:
0454:             *	A mangled version of "component" is appended to "buf".
0455:             *
0456:             *-----------------------------------------------------------------------------
0457:             */
0458:
0459:            private static void appendComponent(String component, // Component to append.
0460:                    int compIndex, // Current index in the component.
0461:                    int compSize, // Index following last in component.
0462:                    StringBuffer buf) // Buffer to append the component.
0463:            {
0464:                for (; compIndex < component.length(); compIndex++) {
0465:                    char c = component.charAt(compIndex);
0466:                    if (c == '/') {
0467:                        // Eliminate duplicate slashes.
0468:
0469:                        while ((compIndex < compSize)
0470:                                && (component.charAt(compIndex + 1) == '/')) {
0471:                            compIndex++;
0472:                        }
0473:
0474:                        // Only add a slash if following non-slash elements exist.
0475:
0476:                        if (compIndex < compSize) {
0477:                            buf.ensureCapacity(buf.length() + 1);
0478:                            buf.append('/');
0479:                        }
0480:                    } else {
0481:                        buf.ensureCapacity(buf.length() + 1);
0482:                        buf.append(c);
0483:                    }
0484:                }
0485:            }
0486:
0487:            /*
0488:             *-----------------------------------------------------------------------------
0489:             *
0490:             * joinPath --
0491:             *
0492:             *	Combine a list of pathes into one path.  It is necessary to perform
0493:             *	system specific operations.
0494:             *
0495:             * Results:
0496:             *	Returns a path String.
0497:             *
0498:             * Side effects:
0499:             *	None.
0500:             *
0501:             *-----------------------------------------------------------------------------
0502:             */
0503:
0504:            static String joinPath(Interp interp, // Current interpreter for path join.
0505:                    TclObject[] argv, // List of pathes to be joined.
0506:                    int startIndex, // 1st item in argv to join.
0507:                    int endIndex) // 1st item to ignore.
0508:                    throws TclException // Thrown if TclList ops fail.
0509:            {
0510:                StringBuffer result = new StringBuffer();
0511:
0512:                switch (JACL.PLATFORM) {
0513:                case JACL.PLATFORM_WINDOWS:
0514:                    // Iterate over all of the components.  If a component is
0515:                    // absolute, then reset the result and start building the
0516:                    // path from the current component on.
0517:
0518:                    for (int i = startIndex; i < endIndex; i++) {
0519:
0520:                        String p = argv[i].toString().replace('\\', '/');
0521:                        int pIndex = 0;
0522:                        int pLastIndex = p.length() - 1;
0523:
0524:                        if (p.length() == 0) {
0525:                            continue;
0526:                        }
0527:
0528:                        StringBuffer absBuf = new StringBuffer();
0529:                        pIndex = getWinAbsPath(p, absBuf);
0530:                        if (pIndex > 0) {
0531:                            // If the path is absolute or volume relative (except those
0532:                            // beginning with '~'), reset the result buffer to the absolute
0533:                            // substring. 
0534:
0535:                            result = absBuf;
0536:                        } else if (p.charAt(0) == '~') {
0537:                            // If the path begins with '~', reset the result buffer to "".
0538:
0539:                            result.setLength(0);
0540:                        } else {
0541:                            // This is a relative path.  Remove the ./ from tilde prefixed
0542:                            // elements unless it is the first component.
0543:
0544:                            if ((result.length() != 0)
0545:                                    && (p.regionMatches(pIndex, "./~", 0, 3))) {
0546:                                pIndex = 2;
0547:                            }
0548:
0549:                            // Check to see if we need to append a separator before adding
0550:                            // this relative component.
0551:
0552:                            if (result.length() != 0) {
0553:                                char c = result.charAt(result.length() - 1);
0554:                                if ((c != '/') /*&& (c != ':')*/) {
0555:                                    result.append('/');
0556:                                }
0557:                            }
0558:                        }
0559:
0560:                        // Append the element.
0561:
0562:                        appendComponent(p, pIndex, pLastIndex, result);
0563:                        pIndex = p.length();
0564:                    }
0565:                    return result.toString();
0566:
0567:                case JACL.PLATFORM_MAC:
0568:                    // Iterate over all of the components.  If a component is
0569:                    // absolute, then reset the result and start building the
0570:                    // path from the current component on.
0571:
0572:                    boolean needsSep = true;
0573:                    for (int i = startIndex; i < endIndex; i++) {
0574:
0575:                        TclObject splitArrayObj[] = TclList.getElements(interp,
0576:                                splitPath(interp, argv[i].toString()));
0577:
0578:                        if (splitArrayObj.length == 0) {
0579:                            continue;
0580:                        }
0581:
0582:                        // If 1st path element is absolute, reset the result to "" and
0583:                        // append the 1st path element to it. 
0584:
0585:                        int start = 0;
0586:                        String p = splitArrayObj[0].toString();
0587:                        if ((p.charAt(0) != ':') && (p.indexOf(':') != -1)) {
0588:                            result.setLength(0);
0589:                            result.append(p);
0590:                            start++;
0591:                            needsSep = false;
0592:                        }
0593:
0594:                        // Now append the rest of the path elements, skipping
0595:                        // : unless it is the first element of the path, and
0596:                        // watching out for :: et al. so we don't end up with
0597:                        // too many colons in the result.
0598:
0599:                        for (int j = start; j < splitArrayObj.length; j++) {
0600:
0601:                            p = splitArrayObj[j].toString();
0602:
0603:                            if (p.equals(":")) {
0604:                                if (result.length() != 0) {
0605:                                    continue;
0606:                                } else {
0607:                                    needsSep = false;
0608:                                }
0609:                            } else {
0610:                                char c = 'o';
0611:                                if (p.length() > 1) {
0612:                                    c = p.charAt(1);
0613:                                }
0614:                                if (p.charAt(0) == ':') {
0615:                                    if (!needsSep) {
0616:                                        p = p.substring(1);
0617:                                    }
0618:                                } else {
0619:                                    if (needsSep) {
0620:                                        result.append(':');
0621:                                    }
0622:                                }
0623:                                if (c == ':') {
0624:                                    needsSep = false;
0625:                                } else {
0626:                                    needsSep = true;
0627:                                }
0628:                            }
0629:                            result.append(p);
0630:                        }
0631:                    }
0632:                    return result.toString();
0633:
0634:                default:
0635:                    // Unix platform.
0636:
0637:                    for (int i = startIndex; i < endIndex; i++) {
0638:
0639:                        String p = argv[i].toString();
0640:                        int pIndex = 0;
0641:                        int pLastIndex = p.length() - 1;
0642:
0643:                        if (p.length() == 0) {
0644:                            continue;
0645:                        }
0646:
0647:                        if (p.charAt(pIndex) == '/') {
0648:                            // If the path is absolute (except those beginning with '~'), 
0649:                            // reset the result buffer to the absolute substring. 
0650:
0651:                            while ((pIndex <= pLastIndex)
0652:                                    && (p.charAt(pIndex) == '/')) {
0653:                                pIndex++;
0654:                            }
0655:                            result.setLength(0);
0656:                            result.append('/');
0657:                        } else if (p.charAt(pIndex) == '~') {
0658:                            // If the path begins with '~', reset the result buffer to "".
0659:
0660:                            result.setLength(0);
0661:                        } else {
0662:                            // This is a relative path.  Remove the ./ from tilde prefixed
0663:                            // elements unless it is the first component.
0664:
0665:                            if ((result.length() != 0)
0666:                                    && (p.regionMatches(pIndex, "./~", 0, 3))) {
0667:                                pIndex += 2;
0668:                            }
0669:
0670:                            // Append a separator if needed.
0671:
0672:                            if ((result.length() != 0)
0673:                                    && (result.charAt(result.length() - 1) != '/')) {
0674:                                result.ensureCapacity(result.length() + 1);
0675:                                result.append('/');
0676:                            }
0677:                        }
0678:
0679:                        // Append the element.
0680:
0681:                        appendComponent(p, pIndex, pLastIndex, result);
0682:                        pIndex = p.length();
0683:                    }
0684:                }
0685:                return result.toString();
0686:            }
0687:
0688:            /*
0689:             *-----------------------------------------------------------------------------
0690:             *
0691:             * splitPath --
0692:             *
0693:             *	Turn one path into a list of components.  It is necessary to perform
0694:             *	system specific operations.
0695:             *
0696:             * Results:
0697:             *	Returns a Tcl List Object.
0698:             *
0699:             * Side effects:
0700:             *	None.
0701:             *
0702:             *-----------------------------------------------------------------------------
0703:             */
0704:
0705:            static TclObject splitPath(Interp interp, // Current interpreter for path split.
0706:                    String path) // Path to be split.
0707:                    throws TclException // Thrown if TclList ops fail.
0708:            {
0709:                TclObject resultListObj = TclList.newInstance();
0710:                TclObject componentObj;
0711:                String component = "";
0712:                String tmpPath;
0713:                boolean foundComponent = false;
0714:                boolean convertDotToColon = false;
0715:                boolean isColonSeparator = false;
0716:                boolean appendColon = false;
0717:                boolean prependColon = false;
0718:                String this Dir = "./";
0719:
0720:                // If the path is the empty string, returnan empty result list.
0721:
0722:                if (path.length() == 0) {
0723:                    return resultListObj;
0724:                }
0725:
0726:                // Handling the 1st component is file system dependent.
0727:
0728:                switch (JACL.PLATFORM) {
0729:                case JACL.PLATFORM_WINDOWS:
0730:                    tmpPath = path.replace('\\', '/');
0731:
0732:                    StringBuffer absBuf = new StringBuffer();
0733:                    int absIndex = getWinAbsPath(tmpPath, absBuf);
0734:                    if (absIndex > 0) {
0735:                        componentObj = TclString.newInstance(absBuf.toString());
0736:                        TclList.append(interp, resultListObj, componentObj);
0737:                        tmpPath = tmpPath.substring(absIndex);
0738:                        foundComponent = true;
0739:                    }
0740:                    break;
0741:
0742:                case JACL.PLATFORM_MAC:
0743:
0744:                    tmpPath = "";
0745:                    this Dir = ":";
0746:
0747:                    switch (path.indexOf(':')) {
0748:                    case -1:
0749:                        // Unix-style name contains no colons.
0750:
0751:                        if (path.charAt(0) != '/') {
0752:                            tmpPath = path;
0753:                            convertDotToColon = true;
0754:                            if (path.charAt(0) == '~') {
0755:                                // If '~' is the first char, then append a colon to end
0756:                                // of the 1st component. 
0757:
0758:                                appendColon = true;
0759:                            }
0760:                            break;
0761:                        }
0762:                        int degenIndex = getDegenerateUnixPath(path);
0763:                        if (degenIndex < path.length()) {
0764:                            // First component of absolute unix path is followed by a ':',
0765:                            // instead of being preceded by a degenerate unix-style
0766:                            // pattern.
0767:
0768:                            tmpPath = path.substring(degenIndex);
0769:                            convertDotToColon = true;
0770:                            appendColon = true;
0771:                            break;
0772:                        }
0773:
0774:                        // Degenerate unix path can't be split.  Return a list with one
0775:                        // element:  ":" prepended to "path".
0776:
0777:                        componentObj = TclString.newInstance(":" + path);
0778:                        TclList.append(interp, resultListObj, componentObj);
0779:                        return resultListObj;
0780:                    case 0:
0781:                        // Relative mac-style name contains a colon in the first position.
0782:
0783:                        if (path.length() == 1) {
0784:                            // If path == ":", then return a list with ":" as its only
0785:                            // element.
0786:
0787:                            componentObj = TclString.newInstance(":");
0788:                            TclList.append(interp, resultListObj, componentObj);
0789:                            return resultListObj;
0790:                        }
0791:
0792:                        // For each component, if slashes exist in the remaining filename,
0793:                        // prepend a colon to the component.  Since this path is relative,
0794:                        // pretend that we have already processed 1 components so a
0795:                        // tilde-prefixed 1st component will have ":" prepended to it.
0796:
0797:                        tmpPath = path.substring(1);
0798:                        foundComponent = true;
0799:                        prependColon = true;
0800:                        isColonSeparator = true;
0801:                        break;
0802:
0803:                    default:
0804:                        // Absolute mac-style name contains a colon, but not in the first
0805:                        // position.   Append a colon to the first component, and, for each
0806:                        // following component, if slashes exist in the remaining filename,
0807:                        // prepend a colon to the component.
0808:
0809:                        tmpPath = path;
0810:                        appendColon = true;
0811:                        prependColon = true;
0812:                        isColonSeparator = true;
0813:                        break;
0814:                    }
0815:                    break;
0816:
0817:                default:
0818:                    // Unix file name: if the first char is a "/", append "/" to the result
0819:                    // list. 
0820:
0821:                    if (path.charAt(0) == '/') {
0822:                        componentObj = TclString.newInstance("/");
0823:                        TclList.append(interp, resultListObj, componentObj);
0824:                        tmpPath = path.substring(1);
0825:                        foundComponent = true;
0826:                    } else {
0827:                        tmpPath = path;
0828:                    }
0829:                }
0830:
0831:                // Iterate over all of the components of the path.
0832:
0833:                int sIndex = 0;
0834:                while (sIndex != -1) {
0835:                    if (isColonSeparator) {
0836:                        sIndex = tmpPath.indexOf(":");
0837:                        // process adjacent ':'
0838:
0839:                        if (sIndex == 0) {
0840:                            componentObj = TclString.newInstance("::");
0841:                            TclList.append(interp, resultListObj, componentObj);
0842:                            foundComponent = true;
0843:                            tmpPath = tmpPath.substring(sIndex + 1);
0844:                            continue;
0845:                        }
0846:                    } else {
0847:                        sIndex = tmpPath.indexOf("/");
0848:                        // Ignore a redundant '/'
0849:
0850:                        if (sIndex == 0) {
0851:                            tmpPath = tmpPath.substring(sIndex + 1);
0852:                            continue;
0853:                        }
0854:                    }
0855:                    if (sIndex == -1) {
0856:                        // Processing the last component.  If it is empty, exit loop.
0857:
0858:                        if (tmpPath.length() == 0) {
0859:                            break;
0860:                        }
0861:                        component = tmpPath;
0862:                    } else {
0863:                        component = tmpPath.substring(0, sIndex);
0864:                    }
0865:
0866:                    if (convertDotToColon
0867:                            && (component.equals(".") || component.equals(".."))) {
0868:                        // If platform = MAC, convert .. to :: or . to :
0869:
0870:                        component = component.replace('.', ':');
0871:                    }
0872:                    if (foundComponent) {
0873:                        if (component.charAt(0) == '~') {
0874:                            // If a '~' preceeds a component (other than the 1st one), then
0875:                            // prepend "./" or ":" to the component.
0876:
0877:                            component = this Dir + component;
0878:                        } else if (prependColon) {
0879:                            // If the prependColon flag is set, either unset it or prepend
0880:                            // ":" to the component, depending on whether any '/'s remain
0881:                            // in tmpPath.
0882:
0883:                            if (tmpPath.indexOf('/') == -1) {
0884:                                prependColon = false;
0885:                            } else {
0886:                                component = ":" + component;
0887:                            }
0888:                        }
0889:                    } else if (appendColon) {
0890:                        //If platform = MAC, append a ':' to the first component.
0891:
0892:                        component = component + ":";
0893:                    }
0894:                    componentObj = TclString.newInstance(component);
0895:                    TclList.append(interp, resultListObj, componentObj);
0896:                    foundComponent = true;
0897:                    tmpPath = tmpPath.substring(sIndex + 1);
0898:                }
0899:                return resultListObj;
0900:            }
0901:
0902:            /*
0903:             *-----------------------------------------------------------------------------
0904:             *
0905:             * doTildeSubst --
0906:             *
0907:             *	Given a string following a tilde, this routine returns the
0908:             *	corresponding home directory.
0909:             *
0910:             * Results:
0911:             *	The result is a string containing the home directory in native format.
0912:             *	Throws an error if it can't find the env(HOME) variable or the
0913:             *	specified user doesn't exist..
0914:             *
0915:             * Side effects:
0916:             *	None.
0917:             *
0918:             *-----------------------------------------------------------------------------
0919:             */
0920:
0921:            static String doTildeSubst(Interp interp, // Current interpreter.
0922:                    String user) // User whose home we must find.
0923:                    throws TclException // Thrown if env(HOME) is not set or if
0924:            //   another user is requested.
0925:            {
0926:                String dir;
0927:
0928:                if (user.length() == 0) {
0929:                    try {
0930:                        dir = interp.getVar("env", "HOME", TCL.GLOBAL_ONLY)
0931:                                .toString();
0932:                    } catch (Exception e) {
0933:                        throw new TclException(interp,
0934:                                "couldn't find HOME environment variable to expand path");
0935:                    }
0936:                    return dir;
0937:                }
0938:
0939:                // WARNING:  Java does not support other users.  "dir" is always null,
0940:                // but it should be the home directory (corresponding to the user name), as
0941:                // specified in the password file.
0942:
0943:                dir = null;
0944:                if (dir == null) {
0945:                    throw new TclException(interp, "user \"" + user
0946:                            + "\" doesn't exist");
0947:                }
0948:                return dir;
0949:            }
0950:
0951:            /*
0952:             *-----------------------------------------------------------------------------
0953:             *
0954:             * translateFileName --
0955:             *
0956:             *	If the path starts with a tilde, do tilde substitution on the first
0957:             *	component and join it with the remainder of the path.
0958:             *	Otherwise, do nothing.
0959:             *
0960:             * Results:
0961:             *	Returns the tilde-substituted path.
0962:             *
0963:             * Side effects:
0964:             *	None.
0965:             *
0966:             *-----------------------------------------------------------------------------
0967:             */
0968:
0969:            static String translateFileName(Interp interp, // Current interpreter for path split.
0970:                    String path) // Path to be split.
0971:                    throws TclException // Thrown if tilde subst fails.
0972:            {
0973:                String fileName = "";
0974:
0975:                if ((path.length() == 0) || (path.charAt(0) != '~')) {
0976:                    // 	    fileName = path;
0977:                    TclObject joinArrayObj[] = new TclObject[1];
0978:                    joinArrayObj[0] = TclString.newInstance(path);
0979:                    fileName = joinPath(interp, joinArrayObj, 0, 1);
0980:                } else {
0981:                    TclObject splitArrayObj[] = TclList.getElements(interp,
0982:                            splitPath(interp, path));
0983:
0984:                    String user = splitArrayObj[0].toString().substring(1);
0985:
0986:                    // Strip the trailing ':' off of a Mac path
0987:                    // before passing the user name to DoTildeSubst.
0988:
0989:                    if ((JACL.PLATFORM == JACL.PLATFORM_MAC)
0990:                            && (user.endsWith(":"))) {
0991:                        user = user.substring(0, user.length() - 1);
0992:                    }
0993:
0994:                    user = doTildeSubst(interp, user);
0995:
0996:                    // 	if (splitArrayObj.length < 2) {
0997:                    // 	    fileName = user;
0998:                    // 	} else {
0999:                    splitArrayObj[0] = TclString.newInstance(user);
1000:                    fileName = joinPath(interp, splitArrayObj, 0,
1001:                            splitArrayObj.length);
1002:                    // 	}
1003:                }
1004:
1005:                // Convert forward slashes to backslashes in Windows paths because
1006:                // some system interfaces don't accept forward slashes.
1007:
1008:                if (JACL.PLATFORM == JACL.PLATFORM_WINDOWS) {
1009:                    fileName = fileName.replace('/', '\\');
1010:                }
1011:                return fileName;
1012:            }
1013:
1014:            /*
1015:             *-----------------------------------------------------------------------------
1016:             *
1017:             * splitAndTranslate --
1018:             *
1019:             *	Split the path.  If there is only one component, and it starts with a
1020:             *	tilde, do tilde substitution and split its result.
1021:             *
1022:             * Results:
1023:             *	Returns a Tcl List Object.
1024:             *
1025:             * Side effects:
1026:             *	None.
1027:             *
1028:             *-----------------------------------------------------------------------------
1029:             */
1030:
1031:            static TclObject splitAndTranslate(Interp interp, // Current interpreter for path split.
1032:                    String path) // Path to be split.
1033:                    throws TclException // Thrown if tilde subst, which may be
1034:            //   called by translateFileName, fails. 
1035:            {
1036:                TclObject splitResult = splitPath(interp, path);
1037:
1038:                int len = TclList.getLength(interp, splitResult);
1039:                if (len == 1) {
1040:                    String fileName = TclList.index(interp, splitResult, 0)
1041:                            .toString();
1042:                    if (fileName.charAt(0) == '~') {
1043:                        String user = translateFileName(interp, fileName);
1044:                        splitResult = splitPath(interp, user);
1045:                    }
1046:                }
1047:                return splitResult;
1048:            }
1049:
1050:        } // end FileUtil class
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.