Source Code Cross Referenced for JavacFileManager.java in  » 6.0-JDK-Modules-sun » javac-compiler » com » sun » tools » javac » util » Java Source Code / Java DocumentationJava Source Code and Java Documentation

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


0001:        /*
0002:         * Copyright 2005-2006 Sun Microsystems, Inc.  All Rights Reserved.
0003:         * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
0004:         *
0005:         * This code is free software; you can redistribute it and/or modify it
0006:         * under the terms of the GNU General Public License version 2 only, as
0007:         * published by the Free Software Foundation.  Sun designates this
0008:         * particular file as subject to the "Classpath" exception as provided
0009:         * by Sun in the LICENSE file that accompanied this code.
0010:         *
0011:         * This code is distributed in the hope that it will be useful, but WITHOUT
0012:         * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
0013:         * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
0014:         * version 2 for more details (a copy is included in the LICENSE file that
0015:         * accompanied this code).
0016:         *
0017:         * You should have received a copy of the GNU General Public License version
0018:         * 2 along with this work; if not, write to the Free Software Foundation,
0019:         * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
0020:         *
0021:         * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
0022:         * CA 95054 USA or visit www.sun.com if you need additional information or
0023:         * have any questions.
0024:         */
0025:
0026:        package com.sun.tools.javac.util;
0027:
0028:        import com.sun.tools.javac.main.JavacOption;
0029:        import com.sun.tools.javac.main.OptionName;
0030:        import com.sun.tools.javac.main.RecognizedOptions;
0031:        import java.io.ByteArrayOutputStream;
0032:        import java.io.File;
0033:        import java.io.FileInputStream;
0034:        import java.io.FileNotFoundException;
0035:        import java.io.FileOutputStream;
0036:        import java.io.IOException;
0037:        import java.io.InputStream;
0038:        import java.io.OutputStream;
0039:        import java.io.OutputStreamWriter;
0040:        import java.io.Writer;
0041:        import java.lang.ref.SoftReference;
0042:        import java.net.MalformedURLException;
0043:        import java.net.URI;
0044:        import java.net.URISyntaxException;
0045:        import java.net.URL;
0046:        import java.net.URLClassLoader;
0047:        import java.nio.ByteBuffer;
0048:        import java.nio.CharBuffer;
0049:        import java.nio.channels.FileChannel;
0050:        import java.nio.charset.Charset;
0051:        import java.nio.charset.CharsetDecoder;
0052:        import java.nio.charset.CoderResult;
0053:        import java.nio.charset.CodingErrorAction;
0054:        import java.nio.charset.IllegalCharsetNameException;
0055:        import java.nio.charset.UnsupportedCharsetException;
0056:        import java.util.ArrayList;
0057:        import java.util.Arrays;
0058:        import java.util.Collection;
0059:        import java.util.Collections;
0060:        import java.util.EnumSet;
0061:        import java.util.Enumeration;
0062:        import java.util.HashMap;
0063:        import java.util.Iterator;
0064:        import java.util.Map;
0065:        import java.util.Set;
0066:        import java.util.zip.ZipEntry;
0067:        import java.util.zip.ZipFile;
0068:
0069:        import javax.lang.model.SourceVersion;
0070:        import javax.tools.FileObject;
0071:        import javax.tools.JavaFileManager;
0072:        import javax.tools.JavaFileObject;
0073:
0074:        import com.sun.tools.javac.code.Source;
0075:        import com.sun.tools.javac.util.JCDiagnostic.SimpleDiagnosticPosition;
0076:        import java.util.concurrent.ConcurrentHashMap;
0077:        import javax.tools.StandardJavaFileManager;
0078:
0079:        import com.sun.tools.javac.zip.*;
0080:        import java.io.ByteArrayInputStream;
0081:
0082:        import static com.sun.tools.javac.main.OptionName.*;
0083:        import static javax.tools.StandardLocation.*;
0084:
0085:        /**
0086:         * This class provides access to the source, class and other files
0087:         * used by the compiler and related tools.
0088:         */
0089:        @Version("@(#)JavacFileManager.java	1.48 07/05/05")
0090:        public class JavacFileManager implements  StandardJavaFileManager {
0091:
0092:            private static final String[] symbolFileLocation = { "lib",
0093:                    "ct.sym" };
0094:            private static final String symbolFilePrefix = "META-INF/sym/rt.jar/";
0095:
0096:            boolean useZipFileIndex;
0097:
0098:            private static int symbolFilePrefixLength = 0;
0099:            static {
0100:                try {
0101:                    symbolFilePrefixLength = symbolFilePrefix.getBytes("UTF-8").length;
0102:                } catch (java.io.UnsupportedEncodingException uee) {
0103:                    // Can't happen...UTF-8 is always supported.
0104:                }
0105:            }
0106:
0107:            private static boolean CHECK_ZIP_TIMESTAMP = false;
0108:            private static Map<File, Boolean> isDirectory = new ConcurrentHashMap<File, Boolean>();
0109:
0110:            public static char[] toArray(CharBuffer buffer) {
0111:                if (buffer.hasArray())
0112:                    return ((CharBuffer) buffer.compact().flip()).array();
0113:                else
0114:                    return buffer.toString().toCharArray();
0115:            }
0116:
0117:            /**
0118:             * The log to be used for error reporting.
0119:             */
0120:            protected Log log;
0121:
0122:            /** Encapsulates knowledge of paths
0123:             */
0124:            private Paths paths;
0125:
0126:            private Options options;
0127:
0128:            private final File uninited = new File("U N I N I T E D");
0129:
0130:            private final Set<JavaFileObject.Kind> sourceOrClass = EnumSet.of(
0131:                    JavaFileObject.Kind.SOURCE, JavaFileObject.Kind.CLASS);
0132:
0133:            /** The standard output directory, primarily used for classes.
0134:             *  Initialized by the "-d" option.
0135:             *  If classOutDir = null, files are written into same directory as the sources
0136:             *  they were generated from.
0137:             */
0138:            private File classOutDir = uninited;
0139:
0140:            /** The output directory, used when generating sources while processing annotations.
0141:             *  Initialized by the "-s" option.
0142:             */
0143:            private File sourceOutDir = uninited;
0144:
0145:            protected boolean mmappedIO;
0146:            protected boolean ignoreSymbolFile;
0147:
0148:            /**
0149:             * User provided charset (through javax.tools).
0150:             */
0151:            protected Charset charset;
0152:
0153:            /**
0154:             * Register a Context.Factory to create a JavacFileManager.
0155:             */
0156:            public static void preRegister(final Context context) {
0157:                context.put(JavaFileManager.class,
0158:                        new Context.Factory<JavaFileManager>() {
0159:                            public JavaFileManager make() {
0160:                                return new JavacFileManager(context, true, null);
0161:                            }
0162:                        });
0163:            }
0164:
0165:            /**
0166:             * Create a JavacFileManager using a given context, optionally registering
0167:             * it as the JavaFileManager for that context.
0168:             */
0169:            public JavacFileManager(Context context, boolean register,
0170:                    Charset charset) {
0171:                if (register)
0172:                    context.put(JavaFileManager.class, this );
0173:                byteBufferCache = new ByteBufferCache();
0174:                this .charset = charset;
0175:                setContext(context);
0176:            }
0177:
0178:            /**
0179:             * Set the context for JavacFileManager.
0180:             */
0181:            public void setContext(Context context) {
0182:                log = Log.instance(context);
0183:                if (paths == null) {
0184:                    paths = Paths.instance(context);
0185:                } else {
0186:                    // Reuse the Paths object as it stores the locations that
0187:                    // have been set with setLocation, etc.
0188:                    paths.setContext(context);
0189:                }
0190:
0191:                options = Options.instance(context);
0192:
0193:                useZipFileIndex = System.getProperty("useJavaUtilZip") == null;// TODO: options.get("useJavaUtilZip") == null;
0194:                CHECK_ZIP_TIMESTAMP = System
0195:                        .getProperty("checkZipIndexTimestamp") != null;// TODO: options.get("checkZipIndexTimestamp") != null;
0196:
0197:                mmappedIO = options.get("mmappedIO") != null;
0198:                ignoreSymbolFile = options.get("ignore.symbol.file") != null;
0199:            }
0200:
0201:            public JavaFileObject getFileForInput(String name) {
0202:                return getRegularFile(new File(name));
0203:            }
0204:
0205:            public JavaFileObject getRegularFile(File file) {
0206:                return new RegularFileObject(file);
0207:            }
0208:
0209:            public JavaFileObject getFileForOutput(String classname,
0210:                    JavaFileObject.Kind kind, JavaFileObject sibling)
0211:                    throws IOException {
0212:                return getJavaFileForOutput(CLASS_OUTPUT, classname, kind,
0213:                        sibling);
0214:            }
0215:
0216:            public Iterable<? extends JavaFileObject> getJavaFileObjectsFromStrings(
0217:                    Iterable<String> names) {
0218:                ListBuffer<File> files = new ListBuffer<File>();
0219:                for (String name : names)
0220:                    files.append(new File(nullCheck(name)));
0221:                return getJavaFileObjectsFromFiles(files.toList());
0222:            }
0223:
0224:            public Iterable<? extends JavaFileObject> getJavaFileObjects(
0225:                    String... names) {
0226:                return getJavaFileObjectsFromStrings(Arrays
0227:                        .asList(nullCheck(names)));
0228:            }
0229:
0230:            protected JavaFileObject.Kind getKind(String extension) {
0231:                if (extension.equals(JavaFileObject.Kind.CLASS.extension))
0232:                    return JavaFileObject.Kind.CLASS;
0233:                else if (extension.equals(JavaFileObject.Kind.SOURCE.extension))
0234:                    return JavaFileObject.Kind.SOURCE;
0235:                else if (extension.equals(JavaFileObject.Kind.HTML.extension))
0236:                    return JavaFileObject.Kind.HTML;
0237:                else
0238:                    return JavaFileObject.Kind.OTHER;
0239:            }
0240:
0241:            private static boolean isValidName(String name) {
0242:                // Arguably, isValidName should reject keywords (such as in SourceVersion.isName() ),
0243:                // but the set of keywords depends on the source level, and we don't want
0244:                // impls of JavaFileManager to have to be dependent on the source level.
0245:                // Therefore we simply check that the argument is a sequence of identifiers
0246:                // separated by ".".
0247:                for (String s : name.split("\\.", -1)) {
0248:                    if (!SourceVersion.isIdentifier(s))
0249:                        return false;
0250:                }
0251:                return true;
0252:            }
0253:
0254:            private static void validateClassName(String className) {
0255:                if (!isValidName(className))
0256:                    throw new IllegalArgumentException("Invalid class name: "
0257:                            + className);
0258:            }
0259:
0260:            private static void validatePackageName(String packageName) {
0261:                if (packageName.length() > 0 && !isValidName(packageName))
0262:                    throw new IllegalArgumentException(
0263:                            "Invalid packageName name: " + packageName);
0264:            }
0265:
0266:            public static void testName(String name,
0267:                    boolean isValidPackageName, boolean isValidClassName) {
0268:                try {
0269:                    validatePackageName(name);
0270:                    if (!isValidPackageName)
0271:                        throw new AssertionError(
0272:                                "Invalid package name accepted: " + name);
0273:                    printAscii("Valid package name: \"%s\"", name);
0274:                } catch (IllegalArgumentException e) {
0275:                    if (isValidPackageName)
0276:                        throw new AssertionError(
0277:                                "Valid package name rejected: " + name);
0278:                    printAscii("Invalid package name: \"%s\"", name);
0279:                }
0280:                try {
0281:                    validateClassName(name);
0282:                    if (!isValidClassName)
0283:                        throw new AssertionError(
0284:                                "Invalid class name accepted: " + name);
0285:                    printAscii("Valid class name: \"%s\"", name);
0286:                } catch (IllegalArgumentException e) {
0287:                    if (isValidClassName)
0288:                        throw new AssertionError("Valid class name rejected: "
0289:                                + name);
0290:                    printAscii("Invalid class name: \"%s\"", name);
0291:                }
0292:            }
0293:
0294:            private static void printAscii(String format, Object... args) {
0295:                String message;
0296:                try {
0297:                    final String ascii = "US-ASCII";
0298:                    message = new String(String.format(null, format, args)
0299:                            .getBytes(ascii), ascii);
0300:                } catch (java.io.UnsupportedEncodingException ex) {
0301:                    throw new AssertionError(ex);
0302:                }
0303:                System.out.println(message);
0304:            }
0305:
0306:            /** Return external representation of name,
0307:             *  converting '.' to File.separatorChar.
0308:             */
0309:            private static String externalizeFileName(CharSequence name) {
0310:                return name.toString().replace('.', File.separatorChar);
0311:            }
0312:
0313:            private static String externalizeFileName(CharSequence n,
0314:                    JavaFileObject.Kind kind) {
0315:                return externalizeFileName(n) + kind.extension;
0316:            }
0317:
0318:            private static String baseName(String fileName) {
0319:                return fileName.substring(fileName
0320:                        .lastIndexOf(File.separatorChar) + 1);
0321:            }
0322:
0323:            /**
0324:             * Insert all files in subdirectory `subdirectory' of `directory' which end
0325:             * in one of the extensions in `extensions' into packageSym.
0326:             */
0327:            private void listDirectory(File directory, String subdirectory,
0328:                    Set<JavaFileObject.Kind> fileKinds, boolean recurse,
0329:                    ListBuffer<JavaFileObject> l) {
0330:                Archive archive = archives.get(directory);
0331:
0332:                boolean isFile = false;
0333:                if (CHECK_ZIP_TIMESTAMP) {
0334:                    Boolean isf = isDirectory.get(directory);
0335:                    if (isf == null) {
0336:                        isFile = directory.isFile();
0337:                        isDirectory.put(directory, isFile);
0338:                    } else {
0339:                        isFile = directory.isFile();
0340:                    }
0341:                } else {
0342:                    isFile = directory.isFile();
0343:                }
0344:
0345:                if (archive != null || isFile) {
0346:                    if (archive == null) {
0347:                        try {
0348:                            archive = openArchive(directory);
0349:                        } catch (IOException ex) {
0350:                            log.error("error.reading.file", directory, ex
0351:                                    .getLocalizedMessage());
0352:                            return;
0353:                        }
0354:                    }
0355:                    if (subdirectory.length() != 0) {
0356:                        if (!useZipFileIndex) {
0357:                            subdirectory = subdirectory.replace('\\', '/');
0358:                            if (!subdirectory.endsWith("/"))
0359:                                subdirectory = subdirectory + "/";
0360:                        } else {
0361:                            if (File.separatorChar == '/') {
0362:                                subdirectory = subdirectory.replace('\\', '/');
0363:                            } else {
0364:                                subdirectory = subdirectory.replace('/', '\\');
0365:                            }
0366:
0367:                            if (!subdirectory.endsWith(File.separator))
0368:                                subdirectory = subdirectory + File.separator;
0369:                        }
0370:                    }
0371:
0372:                    List<String> files = archive.getFiles(subdirectory);
0373:                    if (files != null) {
0374:                        for (String file; !files.isEmpty(); files = files.tail) {
0375:                            file = files.head;
0376:                            if (isValidFile(file, fileKinds)) {
0377:                                l.append(archive.getFileObject(subdirectory,
0378:                                        file));
0379:                            }
0380:                        }
0381:                    }
0382:                    if (recurse) {
0383:                        for (String s : archive.getSubdirectories()) {
0384:                            if (s.startsWith(subdirectory)
0385:                                    && !s.equals(subdirectory)) {
0386:                                // Because the archive map is a flat list of directories,
0387:                                // the enclosing loop will pick up all child subdirectories.
0388:                                // Therefore, there is no need to recurse deeper.
0389:                                listDirectory(directory, s, fileKinds, false, l);
0390:                            }
0391:                        }
0392:                    }
0393:                } else {
0394:                    File d = subdirectory.length() != 0 ? new File(directory,
0395:                            subdirectory) : directory;
0396:                    if (!caseMapCheck(d, subdirectory))
0397:                        return;
0398:
0399:                    File[] files = d.listFiles();
0400:                    if (files == null)
0401:                        return;
0402:
0403:                    for (File f : files) {
0404:                        String fname = f.getName();
0405:                        if (f.isDirectory()) {
0406:                            if (recurse && SourceVersion.isIdentifier(fname)) {
0407:                                listDirectory(directory, subdirectory
0408:                                        + File.separator + fname, fileKinds,
0409:                                        recurse, l);
0410:                            }
0411:                        } else {
0412:                            if (isValidFile(fname, fileKinds)) {
0413:                                JavaFileObject fe = new RegularFileObject(
0414:                                        fname, new File(d, fname));
0415:                                l.append(fe);
0416:                            }
0417:                        }
0418:                    }
0419:                }
0420:            }
0421:
0422:            private boolean isValidFile(String s,
0423:                    Set<JavaFileObject.Kind> fileKinds) {
0424:                int lastDot = s.lastIndexOf(".");
0425:                String extn = (lastDot == -1 ? s : s.substring(lastDot));
0426:                JavaFileObject.Kind kind = getKind(extn);
0427:                return fileKinds.contains(kind);
0428:            }
0429:
0430:            private static final boolean fileSystemIsCaseSensitive = File.separatorChar == '/';
0431:
0432:            /** Hack to make Windows case sensitive. Test whether given path
0433:             *  ends in a string of characters with the same case as given name.
0434:             *  Ignore file separators in both path and name.
0435:             */
0436:            private boolean caseMapCheck(File f, String name) {
0437:                if (fileSystemIsCaseSensitive)
0438:                    return true;
0439:                // Note that getCanonicalPath() returns the case-sensitive
0440:                // spelled file name.
0441:                String path;
0442:                try {
0443:                    path = f.getCanonicalPath();
0444:                } catch (IOException ex) {
0445:                    return false;
0446:                }
0447:                char[] pcs = path.toCharArray();
0448:                char[] ncs = name.toCharArray();
0449:                int i = pcs.length - 1;
0450:                int j = ncs.length - 1;
0451:                while (i >= 0 && j >= 0) {
0452:                    while (i >= 0 && pcs[i] == File.separatorChar)
0453:                        i--;
0454:                    while (j >= 0 && ncs[j] == File.separatorChar)
0455:                        j--;
0456:                    if (i >= 0 && j >= 0) {
0457:                        if (pcs[i] != ncs[j])
0458:                            return false;
0459:                        i--;
0460:                        j--;
0461:                    }
0462:                }
0463:                return j < 0;
0464:            }
0465:
0466:            /**
0467:             * An archive provides a flat directory structure of a ZipFile by
0468:             * mapping directory names to lists of files (basenames).
0469:             */
0470:            public interface Archive {
0471:                void close() throws IOException;
0472:
0473:                boolean contains(String name);
0474:
0475:                JavaFileObject getFileObject(String subdirectory, String file);
0476:
0477:                List<String> getFiles(String subdirectory);
0478:
0479:                Set<String> getSubdirectories();
0480:            }
0481:
0482:            public class ZipArchive implements  Archive {
0483:                protected final Map<String, List<String>> map;
0484:                protected final ZipFile zdir;
0485:
0486:                public ZipArchive(ZipFile zdir) throws IOException {
0487:                    this .zdir = zdir;
0488:                    this .map = new HashMap<String, List<String>>();
0489:                    for (Enumeration<? extends ZipEntry> e = zdir.entries(); e
0490:                            .hasMoreElements();) {
0491:                        ZipEntry entry;
0492:                        try {
0493:                            entry = e.nextElement();
0494:                        } catch (InternalError ex) {
0495:                            IOException io = new IOException();
0496:                            io.initCause(ex); // convenience constructors added in Mustang :-(
0497:                            throw io;
0498:                        }
0499:                        addZipEntry(entry);
0500:                    }
0501:                }
0502:
0503:                void addZipEntry(ZipEntry entry) {
0504:                    String name = entry.getName();
0505:                    int i = name.lastIndexOf('/');
0506:                    String dirname = name.substring(0, i + 1);
0507:                    String basename = name.substring(i + 1);
0508:                    if (basename.length() == 0)
0509:                        return;
0510:                    List<String> list = map.get(dirname);
0511:                    if (list == null)
0512:                        list = List.nil();
0513:                    list = list.prepend(basename);
0514:                    map.put(dirname, list);
0515:                }
0516:
0517:                public boolean contains(String name) {
0518:                    int i = name.lastIndexOf('/');
0519:                    String dirname = name.substring(0, i + 1);
0520:                    String basename = name.substring(i + 1);
0521:                    if (basename.length() == 0)
0522:                        return false;
0523:                    List<String> list = map.get(dirname);
0524:                    return (list != null && list.contains(basename));
0525:                }
0526:
0527:                public List<String> getFiles(String subdirectory) {
0528:                    return map.get(subdirectory);
0529:                }
0530:
0531:                public JavaFileObject getFileObject(String subdirectory,
0532:                        String file) {
0533:                    ZipEntry ze = zdir.getEntry(subdirectory + file);
0534:                    return new ZipFileObject(file, zdir, ze);
0535:                }
0536:
0537:                public Set<String> getSubdirectories() {
0538:                    return map.keySet();
0539:                }
0540:
0541:                public void close() throws IOException {
0542:                    zdir.close();
0543:                }
0544:            }
0545:
0546:            public class SymbolArchive extends ZipArchive {
0547:                final File origFile;
0548:
0549:                public SymbolArchive(File orig, ZipFile zdir)
0550:                        throws IOException {
0551:                    super (zdir);
0552:                    this .origFile = orig;
0553:                }
0554:
0555:                @Override
0556:                void addZipEntry(ZipEntry entry) {
0557:                    // called from super constructor, may not refer to origFile.
0558:                    String name = entry.getName();
0559:                    if (!name.startsWith(symbolFilePrefix))
0560:                        return;
0561:                    name = name.substring(symbolFilePrefix.length());
0562:                    int i = name.lastIndexOf('/');
0563:                    String dirname = name.substring(0, i + 1);
0564:                    String basename = name.substring(i + 1);
0565:                    if (basename.length() == 0)
0566:                        return;
0567:                    List<String> list = map.get(dirname);
0568:                    if (list == null)
0569:                        list = List.nil();
0570:                    list = list.prepend(basename);
0571:                    map.put(dirname, list);
0572:                }
0573:
0574:                @Override
0575:                public JavaFileObject getFileObject(String subdirectory,
0576:                        String file) {
0577:                    return super .getFileObject(symbolFilePrefix + subdirectory,
0578:                            file);
0579:                }
0580:            }
0581:
0582:            public class MissingArchive implements  Archive {
0583:                final File zipFileName;
0584:
0585:                public MissingArchive(File name) {
0586:                    zipFileName = name;
0587:                }
0588:
0589:                public boolean contains(String name) {
0590:                    return false;
0591:                }
0592:
0593:                public void close() {
0594:                }
0595:
0596:                public JavaFileObject getFileObject(String subdirectory,
0597:                        String file) {
0598:                    return null;
0599:                }
0600:
0601:                public List<String> getFiles(String subdirectory) {
0602:                    return List.nil();
0603:                }
0604:
0605:                public Set<String> getSubdirectories() {
0606:                    return Collections.emptySet();
0607:                }
0608:            }
0609:
0610:            /** A directory of zip files already opened.
0611:             */
0612:            Map<File, Archive> archives = new HashMap<File, Archive>();
0613:
0614:            /** Open a new zip file directory.
0615:             */
0616:            protected Archive openArchive(File zipFileName) throws IOException {
0617:                Archive archive = archives.get(zipFileName);
0618:                if (archive == null) {
0619:                    File origZipFileName = zipFileName;
0620:                    if (!ignoreSymbolFile
0621:                            && paths.isBootClassPathRtJar(zipFileName)) {
0622:                        File file = zipFileName.getParentFile().getParentFile(); // ${java.home}
0623:                        if (new File(file.getName()).equals(new File("jre")))
0624:                            file = file.getParentFile();
0625:                        // file == ${jdk.home}
0626:                        for (String name : symbolFileLocation)
0627:                            file = new File(file, name);
0628:                        // file == ${jdk.home}/lib/ct.sym
0629:                        if (file.exists())
0630:                            zipFileName = file;
0631:                    }
0632:
0633:                    try {
0634:
0635:                        ZipFile zdir = null;
0636:
0637:                        boolean usePreindexedCache = false;
0638:                        String preindexCacheLocation = null;
0639:
0640:                        if (!useZipFileIndex) {
0641:                            zdir = new ZipFile(zipFileName);
0642:                        } else {
0643:                            usePreindexedCache = options.get("usezipindex") != null;
0644:                            preindexCacheLocation = options
0645:                                    .get("java.io.tmpdir");
0646:                            String optCacheLoc = options
0647:                                    .get("cachezipindexdir");
0648:
0649:                            if (optCacheLoc != null
0650:                                    && optCacheLoc.length() != 0) {
0651:                                if (optCacheLoc.startsWith("\"")) {
0652:                                    if (optCacheLoc.endsWith("\"")) {
0653:                                        optCacheLoc = optCacheLoc.substring(1,
0654:                                                optCacheLoc.length() - 1);
0655:                                    } else {
0656:                                        optCacheLoc = optCacheLoc.substring(1);
0657:                                    }
0658:                                }
0659:
0660:                                File cacheDir = new File(optCacheLoc);
0661:                                if (cacheDir.exists() && cacheDir.canWrite()) {
0662:                                    preindexCacheLocation = optCacheLoc;
0663:                                    if (!preindexCacheLocation.endsWith("/")
0664:                                            && !preindexCacheLocation
0665:                                                    .endsWith(File.separator)) {
0666:                                        preindexCacheLocation += File.separator;
0667:                                    }
0668:                                }
0669:                            }
0670:                        }
0671:
0672:                        if (origZipFileName == zipFileName) {
0673:                            if (!useZipFileIndex) {
0674:                                archive = new ZipArchive(zdir);
0675:                            } else {
0676:                                archive = new ZipFileIndexArchive(
0677:                                        this ,
0678:                                        ZipFileIndex
0679:                                                .getZipFileIndex(
0680:                                                        zipFileName,
0681:                                                        0,
0682:                                                        usePreindexedCache,
0683:                                                        preindexCacheLocation,
0684:                                                        options
0685:                                                                .get("writezipindexfiles") != null));
0686:                            }
0687:                        } else {
0688:                            if (!useZipFileIndex) {
0689:                                archive = new SymbolArchive(origZipFileName,
0690:                                        zdir);
0691:                            } else {
0692:                                archive = new ZipFileIndexArchive(
0693:                                        this ,
0694:                                        ZipFileIndex
0695:                                                .getZipFileIndex(
0696:                                                        zipFileName,
0697:                                                        symbolFilePrefixLength,
0698:                                                        usePreindexedCache,
0699:                                                        preindexCacheLocation,
0700:                                                        options
0701:                                                                .get("writezipindexfiles") != null));
0702:                            }
0703:                        }
0704:                    } catch (FileNotFoundException ex) {
0705:                        archive = new MissingArchive(zipFileName);
0706:                    } catch (IOException ex) {
0707:                        log.error("error.reading.file", zipFileName, ex
0708:                                .getLocalizedMessage());
0709:                        archive = new MissingArchive(zipFileName);
0710:                    }
0711:
0712:                    archives.put(origZipFileName, archive);
0713:                }
0714:                return archive;
0715:            }
0716:
0717:            /** Flush any output resources.
0718:             */
0719:            public void flush() {
0720:                contentCache.clear();
0721:            }
0722:
0723:            /**
0724:             * Close the JavaFileManager, releasing resources.
0725:             */
0726:            public void close() {
0727:                for (Iterator<Archive> i = archives.values().iterator(); i
0728:                        .hasNext();) {
0729:                    Archive a = i.next();
0730:                    i.remove();
0731:                    try {
0732:                        a.close();
0733:                    } catch (IOException e) {
0734:                    }
0735:                }
0736:            }
0737:
0738:            private Map<JavaFileObject, SoftReference<CharBuffer>> contentCache = new HashMap<JavaFileObject, SoftReference<CharBuffer>>();
0739:
0740:            private String defaultEncodingName;
0741:
0742:            private String getDefaultEncodingName() {
0743:                if (defaultEncodingName == null) {
0744:                    defaultEncodingName = new OutputStreamWriter(
0745:                            new ByteArrayOutputStream()).getEncoding();
0746:                }
0747:                return defaultEncodingName;
0748:            }
0749:
0750:            protected String getEncodingName() {
0751:                String encName = options.get(OptionName.ENCODING);
0752:                if (encName == null)
0753:                    return getDefaultEncodingName();
0754:                else
0755:                    return encName;
0756:            }
0757:
0758:            protected Source getSource() {
0759:                String sourceName = options.get(OptionName.SOURCE);
0760:                Source source = null;
0761:                if (sourceName != null)
0762:                    source = Source.lookup(sourceName);
0763:                return (source != null ? source : Source.DEFAULT);
0764:            }
0765:
0766:            /**
0767:             * Make a byte buffer from an input stream.
0768:             */
0769:            private ByteBuffer makeByteBuffer(InputStream in)
0770:                    throws IOException {
0771:                int limit = in.available();
0772:                if (mmappedIO && in instanceof  FileInputStream) {
0773:                    // Experimental memory mapped I/O
0774:                    FileInputStream fin = (FileInputStream) in;
0775:                    return fin.getChannel().map(FileChannel.MapMode.READ_ONLY,
0776:                            0, limit);
0777:                }
0778:                if (limit < 1024)
0779:                    limit = 1024;
0780:                ByteBuffer result = byteBufferCache.get(limit);
0781:                int position = 0;
0782:                while (in.available() != 0) {
0783:                    if (position >= limit)
0784:                        // expand buffer
0785:                        result = ByteBuffer.allocate(limit <<= 1).put(
0786:                                (ByteBuffer) result.flip());
0787:                    int count = in.read(result.array(), position, limit
0788:                            - position);
0789:                    if (count < 0)
0790:                        break;
0791:                    result.position(position += count);
0792:                }
0793:                return (ByteBuffer) result.flip();
0794:            }
0795:
0796:            /**
0797:             * A single-element cache of direct byte buffers.
0798:             */
0799:            private static class ByteBufferCache {
0800:                private ByteBuffer cached;
0801:
0802:                ByteBuffer get(int capacity) {
0803:                    if (capacity < 20480)
0804:                        capacity = 20480;
0805:                    ByteBuffer result = (cached != null && cached.capacity() >= capacity) ? (ByteBuffer) cached
0806:                            .clear()
0807:                            : ByteBuffer.allocate(capacity + capacity >> 1);
0808:                    cached = null;
0809:                    return result;
0810:                }
0811:
0812:                void put(ByteBuffer x) {
0813:                    cached = x;
0814:                }
0815:            }
0816:
0817:            private final ByteBufferCache byteBufferCache;
0818:
0819:            private CharsetDecoder getDecoder(String encodingName,
0820:                    boolean ignoreEncodingErrors) {
0821:                Charset charset = (this .charset == null) ? Charset
0822:                        .forName(encodingName) : this .charset;
0823:                CharsetDecoder decoder = charset.newDecoder();
0824:
0825:                CodingErrorAction action;
0826:                if (ignoreEncodingErrors)
0827:                    action = CodingErrorAction.REPLACE;
0828:                else
0829:                    action = CodingErrorAction.REPORT;
0830:
0831:                return decoder.onMalformedInput(action).onUnmappableCharacter(
0832:                        action);
0833:            }
0834:
0835:            /**
0836:             * Decode a ByteBuffer into a CharBuffer.
0837:             */
0838:            private CharBuffer decode(ByteBuffer inbuf,
0839:                    boolean ignoreEncodingErrors) {
0840:                String encodingName = getEncodingName();
0841:                CharsetDecoder decoder;
0842:                try {
0843:                    decoder = getDecoder(encodingName, ignoreEncodingErrors);
0844:                } catch (IllegalCharsetNameException e) {
0845:                    log.error("unsupported.encoding", encodingName);
0846:                    return (CharBuffer) CharBuffer.allocate(1).flip();
0847:                } catch (UnsupportedCharsetException e) {
0848:                    log.error("unsupported.encoding", encodingName);
0849:                    return (CharBuffer) CharBuffer.allocate(1).flip();
0850:                }
0851:
0852:                // slightly overestimate the buffer size to avoid reallocation.
0853:                float factor = decoder.averageCharsPerByte() * 0.8f
0854:                        + decoder.maxCharsPerByte() * 0.2f;
0855:                CharBuffer dest = CharBuffer.allocate(10 + (int) (inbuf
0856:                        .remaining() * factor));
0857:
0858:                while (true) {
0859:                    CoderResult result = decoder.decode(inbuf, dest, true);
0860:                    dest.flip();
0861:
0862:                    if (result.isUnderflow()) { // done reading
0863:                        // make sure there is at least one extra character
0864:                        if (dest.limit() == dest.capacity()) {
0865:                            dest = CharBuffer.allocate(dest.capacity() + 1)
0866:                                    .put(dest);
0867:                            dest.flip();
0868:                        }
0869:                        return dest;
0870:                    } else if (result.isOverflow()) { // buffer too small; expand
0871:                        int newCapacity = 10
0872:                                + dest.capacity()
0873:                                + (int) (inbuf.remaining() * decoder
0874:                                        .maxCharsPerByte());
0875:                        dest = CharBuffer.allocate(newCapacity).put(dest);
0876:                    } else if (result.isMalformed() || result.isUnmappable()) {
0877:                        // bad character in input
0878:
0879:                        // report coding error (warn only pre 1.5)
0880:                        if (!getSource().allowEncodingErrors()) {
0881:                            log.error(
0882:                                    new SimpleDiagnosticPosition(dest.limit()),
0883:                                    "illegal.char.for.encoding",
0884:                                    charset == null ? encodingName : charset
0885:                                            .name());
0886:                        } else {
0887:                            log.warning(new SimpleDiagnosticPosition(dest
0888:                                    .limit()), "illegal.char.for.encoding",
0889:                                    charset == null ? encodingName : charset
0890:                                            .name());
0891:                        }
0892:
0893:                        // skip past the coding error
0894:                        inbuf.position(inbuf.position() + result.length());
0895:
0896:                        // undo the flip() to prepare the output buffer
0897:                        // for more translation
0898:                        dest.position(dest.limit());
0899:                        dest.limit(dest.capacity());
0900:                        dest.put((char) 0xfffd); // backward compatible
0901:                    } else {
0902:                        throw new AssertionError(result);
0903:                    }
0904:                }
0905:                // unreached
0906:            }
0907:
0908:            public ClassLoader getClassLoader(Location location) {
0909:                nullCheck(location);
0910:                Iterable<? extends File> path = getLocation(location);
0911:                if (path == null)
0912:                    return null;
0913:                ListBuffer<URL> lb = new ListBuffer<URL>();
0914:                for (File f : path) {
0915:                    try {
0916:                        lb.append(f.toURI().toURL());
0917:                    } catch (MalformedURLException e) {
0918:                        throw new AssertionError(e);
0919:                    }
0920:                }
0921:                return new URLClassLoader(lb.toArray(new URL[lb.size()]),
0922:                        getClass().getClassLoader());
0923:            }
0924:
0925:            public Iterable<JavaFileObject> list(Location location,
0926:                    String packageName, Set<JavaFileObject.Kind> kinds,
0927:                    boolean recurse) throws IOException {
0928:                // validatePackageName(packageName);
0929:                nullCheck(packageName);
0930:                nullCheck(kinds);
0931:
0932:                Iterable<? extends File> path = getLocation(location);
0933:                if (path == null)
0934:                    return List.nil();
0935:                String subdirectory = externalizeFileName(packageName);
0936:                ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
0937:
0938:                for (File directory : path)
0939:                    listDirectory(directory, subdirectory, kinds, recurse,
0940:                            results);
0941:
0942:                return results.toList();
0943:            }
0944:
0945:            public String inferBinaryName(Location location, JavaFileObject file) {
0946:                file.getClass(); // null check
0947:                location.getClass(); // null check
0948:                // Need to match the path semantics of list(location, ...)
0949:                Iterable<? extends File> path = getLocation(location);
0950:                if (path == null) {
0951:                    //System.err.println("Path for " + location + " is null");
0952:                    return null;
0953:                }
0954:                //System.err.println("Path for " + location + " is " + path);
0955:
0956:                if (file instanceof  RegularFileObject) {
0957:                    RegularFileObject r = (RegularFileObject) file;
0958:                    String rPath = r.getPath();
0959:                    //System.err.println("RegularFileObject " + file + " " +r.getPath());
0960:                    for (File dir : path) {
0961:                        //System.err.println("dir: " + dir);
0962:                        String dPath = dir.getPath();
0963:                        if (!dPath.endsWith(File.separator))
0964:                            dPath += File.separator;
0965:                        if (rPath.regionMatches(true, 0, dPath, 0, dPath
0966:                                .length())
0967:                                && new File(rPath.substring(0, dPath.length()))
0968:                                        .equals(new File(dPath))) {
0969:                            String relativeName = rPath.substring(dPath
0970:                                    .length());
0971:                            return removeExtension(relativeName).replace(
0972:                                    File.separatorChar, '.');
0973:                        }
0974:                    }
0975:                } else if (file instanceof  ZipFileObject) {
0976:                    ZipFileObject z = (ZipFileObject) file;
0977:                    String entryName = z.getZipEntryName();
0978:                    if (entryName.startsWith(symbolFilePrefix))
0979:                        entryName = entryName.substring(symbolFilePrefix
0980:                                .length());
0981:                    return removeExtension(entryName).replace('/', '.');
0982:                } else if (file instanceof  ZipFileIndexFileObject) {
0983:                    ZipFileIndexFileObject z = (ZipFileIndexFileObject) file;
0984:                    String entryName = z.getZipEntryName();
0985:                    if (entryName.startsWith(symbolFilePrefix))
0986:                        entryName = entryName.substring(symbolFilePrefix
0987:                                .length());
0988:                    return removeExtension(entryName).replace(
0989:                            File.separatorChar, '.');
0990:                } else
0991:                    throw new IllegalArgumentException(file.getClass()
0992:                            .getName());
0993:                // System.err.println("inferBinaryName failed for " + file);
0994:                return null;
0995:            }
0996:
0997:            // where
0998:            private static String removeExtension(String fileName) {
0999:                int lastDot = fileName.lastIndexOf(".");
1000:                return (lastDot == -1 ? fileName : fileName.substring(0,
1001:                        lastDot));
1002:            }
1003:
1004:            public boolean isSameFile(FileObject a, FileObject b) {
1005:                nullCheck(a);
1006:                nullCheck(b);
1007:                if (!(a instanceof  BaseFileObject))
1008:                    throw new IllegalArgumentException("Not supported: " + a);
1009:                if (!(b instanceof  BaseFileObject))
1010:                    throw new IllegalArgumentException("Not supported: " + b);
1011:                return a.equals(b);
1012:            }
1013:
1014:            public boolean handleOption(String current,
1015:                    Iterator<String> remaining) {
1016:                for (JavacOption o : javacFileManagerOptions) {
1017:                    if (o.matches(current)) {
1018:                        if (o.hasArg()) {
1019:                            if (remaining.hasNext()) {
1020:                                if (!o.process(options, current, remaining
1021:                                        .next()))
1022:                                    return true;
1023:                            }
1024:                        } else {
1025:                            if (!o.process(options, current))
1026:                                return true;
1027:                        }
1028:                        // operand missing, or process returned false
1029:                        throw new IllegalArgumentException(current);
1030:                    }
1031:                }
1032:
1033:                return false;
1034:            }
1035:
1036:            // where
1037:            private static JavacOption[] javacFileManagerOptions = RecognizedOptions
1038:                    .getJavacFileManagerOptions(new RecognizedOptions.GrumpyHelper());
1039:
1040:            public int isSupportedOption(String option) {
1041:                for (JavacOption o : javacFileManagerOptions) {
1042:                    if (o.matches(option))
1043:                        return o.hasArg() ? 1 : 0;
1044:                }
1045:                return -1;
1046:            }
1047:
1048:            public boolean hasLocation(Location location) {
1049:                return getLocation(location) != null;
1050:            }
1051:
1052:            public JavaFileObject getJavaFileForInput(Location location,
1053:                    String className, JavaFileObject.Kind kind)
1054:                    throws IOException {
1055:                nullCheck(location);
1056:                // validateClassName(className);
1057:                nullCheck(className);
1058:                nullCheck(kind);
1059:                if (!sourceOrClass.contains(kind))
1060:                    throw new IllegalArgumentException("Invalid kind " + kind);
1061:                return getFileForInput(location, externalizeFileName(className,
1062:                        kind));
1063:            }
1064:
1065:            public FileObject getFileForInput(Location location,
1066:                    String packageName, String relativeName) throws IOException {
1067:                nullCheck(location);
1068:                // validatePackageName(packageName);
1069:                nullCheck(packageName);
1070:                if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701
1071:                    throw new IllegalArgumentException(
1072:                            "Invalid relative name: " + relativeName);
1073:                String name = packageName.length() == 0 ? relativeName
1074:                        : new File(externalizeFileName(packageName),
1075:                                relativeName).getPath();
1076:                return getFileForInput(location, name);
1077:            }
1078:
1079:            private JavaFileObject getFileForInput(Location location,
1080:                    String name) throws IOException {
1081:                Iterable<? extends File> path = getLocation(location);
1082:                if (path == null)
1083:                    return null;
1084:
1085:                for (File dir : path) {
1086:                    if (dir.isDirectory()) {
1087:                        File f = new File(dir, name.replace('/',
1088:                                File.separatorChar));
1089:                        if (f.exists())
1090:                            return new RegularFileObject(f);
1091:                    } else {
1092:                        Archive a = openArchive(dir);
1093:                        if (a.contains(name)) {
1094:                            int i = name.lastIndexOf('/');
1095:                            String dirname = name.substring(0, i + 1);
1096:                            String basename = name.substring(i + 1);
1097:                            return a.getFileObject(dirname, basename);
1098:                        }
1099:
1100:                    }
1101:                }
1102:                return null;
1103:
1104:            }
1105:
1106:            public JavaFileObject getJavaFileForOutput(Location location,
1107:                    String className, JavaFileObject.Kind kind,
1108:                    FileObject sibling) throws IOException {
1109:                nullCheck(location);
1110:                // validateClassName(className);
1111:                nullCheck(className);
1112:                nullCheck(kind);
1113:                if (!sourceOrClass.contains(kind))
1114:                    throw new IllegalArgumentException("Invalid kind " + kind);
1115:                return getFileForOutput(location, externalizeFileName(
1116:                        className, kind), sibling);
1117:            }
1118:
1119:            public FileObject getFileForOutput(Location location,
1120:                    String packageName, String relativeName, FileObject sibling)
1121:                    throws IOException {
1122:                nullCheck(location);
1123:                // validatePackageName(packageName);
1124:                nullCheck(packageName);
1125:                if (!isRelativeUri(URI.create(relativeName))) // FIXME 6419701
1126:                    throw new IllegalArgumentException(
1127:                            "relativeName is invalid");
1128:                String name = packageName.length() == 0 ? relativeName
1129:                        : new File(externalizeFileName(packageName),
1130:                                relativeName).getPath();
1131:                return getFileForOutput(location, name, sibling);
1132:            }
1133:
1134:            private JavaFileObject getFileForOutput(Location location,
1135:                    String fileName, FileObject sibling) throws IOException {
1136:                File dir;
1137:                if (location == CLASS_OUTPUT) {
1138:                    if (getClassOutDir() != null) {
1139:                        dir = getClassOutDir();
1140:                    } else {
1141:                        File siblingDir = null;
1142:                        if (sibling != null
1143:                                && sibling instanceof  RegularFileObject) {
1144:                            siblingDir = ((RegularFileObject) sibling).f
1145:                                    .getParentFile();
1146:                        }
1147:                        return new RegularFileObject(new File(siblingDir,
1148:                                baseName(fileName)));
1149:                    }
1150:                } else if (location == SOURCE_OUTPUT) {
1151:                    dir = (getSourceOutDir() != null ? getSourceOutDir()
1152:                            : getClassOutDir());
1153:                } else {
1154:                    Iterable<? extends File> path = paths
1155:                            .getPathForLocation(location);
1156:                    dir = null;
1157:                    for (File f : path) {
1158:                        dir = f;
1159:                        break;
1160:                    }
1161:                }
1162:
1163:                File file = (dir == null ? new File(fileName) : new File(dir,
1164:                        fileName));
1165:                return new RegularFileObject(file);
1166:
1167:            }
1168:
1169:            public Iterable<? extends JavaFileObject> getJavaFileObjectsFromFiles(
1170:                    Iterable<? extends File> files) {
1171:                ArrayList<RegularFileObject> result;
1172:                if (files instanceof  Collection)
1173:                    result = new ArrayList<RegularFileObject>(
1174:                            ((Collection) files).size());
1175:                else
1176:                    result = new ArrayList<RegularFileObject>();
1177:                for (File f : files)
1178:                    result.add(new RegularFileObject(nullCheck(f)));
1179:                return result;
1180:            }
1181:
1182:            public Iterable<? extends JavaFileObject> getJavaFileObjects(
1183:                    File... files) {
1184:                return getJavaFileObjectsFromFiles(Arrays
1185:                        .asList(nullCheck(files)));
1186:            }
1187:
1188:            public void setLocation(Location location,
1189:                    Iterable<? extends File> path) throws IOException {
1190:                nullCheck(location);
1191:                paths.lazy();
1192:
1193:                final File dir = location.isOutputLocation() ? getOutputDirectory(path)
1194:                        : null;
1195:
1196:                if (location == CLASS_OUTPUT)
1197:                    classOutDir = getOutputLocation(dir, D);
1198:                else if (location == SOURCE_OUTPUT)
1199:                    sourceOutDir = getOutputLocation(dir, S);
1200:                else
1201:                    paths.setPathForLocation(location, path);
1202:            }
1203:
1204:            // where
1205:            private File getOutputDirectory(Iterable<? extends File> path)
1206:                    throws IOException {
1207:                if (path == null)
1208:                    return null;
1209:                Iterator<? extends File> pathIter = path.iterator();
1210:                if (!pathIter.hasNext())
1211:                    throw new IllegalArgumentException(
1212:                            "empty path for directory");
1213:                File dir = pathIter.next();
1214:                if (pathIter.hasNext())
1215:                    throw new IllegalArgumentException(
1216:                            "path too long for directory");
1217:                if (!dir.exists())
1218:                    throw new FileNotFoundException(dir + ": does not exist");
1219:                else if (!dir.isDirectory())
1220:                    throw new IOException(dir + ": not a directory");
1221:                return dir;
1222:            }
1223:
1224:            private File getOutputLocation(File dir,
1225:                    OptionName defaultOptionName) {
1226:                if (dir != null)
1227:                    return dir;
1228:                String arg = options.get(defaultOptionName);
1229:                if (arg == null)
1230:                    return null;
1231:                return new File(arg);
1232:            }
1233:
1234:            public Iterable<? extends File> getLocation(Location location) {
1235:                nullCheck(location);
1236:                paths.lazy();
1237:                if (location == CLASS_OUTPUT) {
1238:                    return (getClassOutDir() == null ? null : List
1239:                            .of(getClassOutDir()));
1240:                } else if (location == SOURCE_OUTPUT) {
1241:                    return (getSourceOutDir() == null ? null : List
1242:                            .of(getSourceOutDir()));
1243:                } else
1244:                    return paths.getPathForLocation(location);
1245:            }
1246:
1247:            private File getClassOutDir() {
1248:                if (classOutDir == uninited)
1249:                    classOutDir = getOutputLocation(null, D);
1250:                return classOutDir;
1251:            }
1252:
1253:            private File getSourceOutDir() {
1254:                if (sourceOutDir == uninited)
1255:                    sourceOutDir = getOutputLocation(null, S);
1256:                return sourceOutDir;
1257:            }
1258:
1259:            /**
1260:             * Enforces the specification of a "relative" URI as used in
1261:             * {@linkplain #getFileForInput(Location,String,URI)
1262:             * getFileForInput}.  This method must follow the rules defined in
1263:             * that method, do not make any changes without consulting the
1264:             * specification.
1265:             */
1266:            protected static boolean isRelativeUri(URI uri) {
1267:                if (uri.isAbsolute())
1268:                    return false;
1269:                String path = uri.normalize().getPath();
1270:                if (path.length() == 0 /* isEmpty() is mustang API */)
1271:                    return false;
1272:                char first = path.charAt(0);
1273:                return first != '.' && first != '/';
1274:            }
1275:
1276:            /**
1277:             * Converts a relative file name to a relative URI.  This is
1278:             * different from File.toURI as this method does not canonicalize
1279:             * the file before creating the URI.  Furthermore, no schema is
1280:             * used.
1281:             * @param file a relative file name
1282:             * @return a relative URI
1283:             * @throws IllegalArgumentException if the file name is not
1284:             * relative according to the definition given in {@link
1285:             * javax.tools.JavaFileManager#getFileForInput}
1286:             */
1287:            public static String getRelativeName(File file) {
1288:                if (!file.isAbsolute()) {
1289:                    String result = file.getPath().replace(File.separatorChar,
1290:                            '/');
1291:                    if (JavacFileManager.isRelativeUri(URI.create(result))) // FIXME 6419701
1292:                        return result;
1293:                }
1294:                throw new IllegalArgumentException("Invalid relative path: "
1295:                        + file);
1296:            }
1297:
1298:            @SuppressWarnings("deprecation")
1299:            // bug 6410637
1300:            protected static String getJavacFileName(FileObject file) {
1301:                if (file instanceof  BaseFileObject)
1302:                    return ((BaseFileObject) file).getPath();
1303:                URI uri = file.toUri();
1304:                String scheme = uri.getScheme();
1305:                if (scheme == null || scheme.equals("file")
1306:                        || scheme.equals("jar"))
1307:                    return uri.getPath();
1308:                else
1309:                    return uri.toString();
1310:            }
1311:
1312:            @SuppressWarnings("deprecation")
1313:            // bug 6410637
1314:            protected static String getJavacBaseFileName(FileObject file) {
1315:                if (file instanceof  BaseFileObject)
1316:                    return ((BaseFileObject) file).getName();
1317:                URI uri = file.toUri();
1318:                String scheme = uri.getScheme();
1319:                if (scheme == null || scheme.equals("file")
1320:                        || scheme.equals("jar")) {
1321:                    String path = uri.getPath();
1322:                    if (path == null)
1323:                        return null;
1324:                    if (scheme != null && scheme.equals("jar"))
1325:                        path = path.substring(path.lastIndexOf('!') + 1);
1326:                    return path.substring(path.lastIndexOf('/') + 1);
1327:                } else {
1328:                    return uri.toString();
1329:                }
1330:            }
1331:
1332:            private static <T> T nullCheck(T o) {
1333:                o.getClass(); // null check
1334:                return o;
1335:            }
1336:
1337:            private static <T> Iterable<T> nullCheck(Iterable<T> it) {
1338:                for (T t : it)
1339:                    t.getClass(); // null check
1340:                return it;
1341:            }
1342:
1343:            /**
1344:             * A subclass of JavaFileObject representing regular files.
1345:             */
1346:            private class RegularFileObject extends BaseFileObject {
1347:                /** Have the parent directories been created?
1348:                 */
1349:                private boolean hasParents = false;
1350:
1351:                /** The file's name.
1352:                 */
1353:                private String name;
1354:
1355:                /** The underlying file.
1356:                 */
1357:                final File f;
1358:
1359:                public RegularFileObject(File f) {
1360:                    this (f.getName(), f);
1361:                }
1362:
1363:                public RegularFileObject(String name, File f) {
1364:                    if (f.isDirectory())
1365:                        throw new IllegalArgumentException(
1366:                                "directories not supported");
1367:                    this .name = name;
1368:                    this .f = f;
1369:                }
1370:
1371:                public InputStream openInputStream() throws IOException {
1372:                    return new FileInputStream(f);
1373:                }
1374:
1375:                protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
1376:                    return JavacFileManager.this .getDecoder(getEncodingName(),
1377:                            ignoreEncodingErrors);
1378:                }
1379:
1380:                public OutputStream openOutputStream() throws IOException {
1381:                    ensureParentDirectoriesExist();
1382:                    return new FileOutputStream(f);
1383:                }
1384:
1385:                public Writer openWriter() throws IOException {
1386:                    ensureParentDirectoriesExist();
1387:                    return new OutputStreamWriter(new FileOutputStream(f),
1388:                            getEncodingName());
1389:                }
1390:
1391:                private void ensureParentDirectoriesExist() throws IOException {
1392:                    if (!hasParents) {
1393:                        File parent = f.getParentFile();
1394:                        if (parent != null && !parent.exists()) {
1395:                            if (!parent.mkdirs()) {
1396:                                // if the mkdirs failed, it may be because another process concurrently
1397:                                // created the directory, so check if the directory got created
1398:                                // anyway before throwing an exception
1399:                                if (!parent.exists() || !parent.isDirectory())
1400:                                    throw new IOException(
1401:                                            "could not create parent directories");
1402:                            }
1403:                        }
1404:                        hasParents = true;
1405:                    }
1406:                }
1407:
1408:                /** @deprecated see bug 6410637 */
1409:                @Deprecated
1410:                public String getName() {
1411:                    return name;
1412:                }
1413:
1414:                public boolean isNameCompatible(String cn,
1415:                        JavaFileObject.Kind kind) {
1416:                    cn.getClass(); // null check
1417:                    if (kind == Kind.OTHER && getKind() != kind)
1418:                        return false;
1419:                    String n = cn + kind.extension;
1420:                    if (name.equals(n))
1421:                        return true;
1422:                    if (name.equalsIgnoreCase(n)) {
1423:                        try {
1424:                            // allow for Windows
1425:                            return (f.getCanonicalFile().getName().equals(n));
1426:                        } catch (IOException e) {
1427:                        }
1428:                    }
1429:                    return false;
1430:                }
1431:
1432:                /** @deprecated see bug 6410637 */
1433:                @Deprecated
1434:                public String getPath() {
1435:                    return f.getPath();
1436:                }
1437:
1438:                public long getLastModified() {
1439:                    return f.lastModified();
1440:                }
1441:
1442:                public boolean delete() {
1443:                    return f.delete();
1444:                }
1445:
1446:                public CharBuffer getCharContent(boolean ignoreEncodingErrors)
1447:                        throws IOException {
1448:                    SoftReference<CharBuffer> r = contentCache.get(this );
1449:                    CharBuffer cb = (r == null ? null : r.get());
1450:                    if (cb == null) {
1451:                        InputStream in = new FileInputStream(f);
1452:                        try {
1453:                            ByteBuffer bb = makeByteBuffer(in);
1454:                            JavaFileObject prev = log.useSource(this );
1455:                            try {
1456:                                cb = decode(bb, ignoreEncodingErrors);
1457:                            } finally {
1458:                                log.useSource(prev);
1459:                            }
1460:                            byteBufferCache.put(bb); // save for next time
1461:                            if (!ignoreEncodingErrors)
1462:                                contentCache.put(this ,
1463:                                        new SoftReference<CharBuffer>(cb));
1464:                        } finally {
1465:                            in.close();
1466:                        }
1467:                    }
1468:                    return cb;
1469:                }
1470:
1471:                @Override
1472:                public boolean equals(Object other) {
1473:                    if (!(other instanceof  RegularFileObject))
1474:                        return false;
1475:                    RegularFileObject o = (RegularFileObject) other;
1476:                    try {
1477:                        return f.equals(o.f)
1478:                                || f.getCanonicalFile().equals(
1479:                                        o.f.getCanonicalFile());
1480:                    } catch (IOException e) {
1481:                        return false;
1482:                    }
1483:                }
1484:
1485:                @Override
1486:                public int hashCode() {
1487:                    return f.hashCode();
1488:                }
1489:
1490:                public URI toUri() {
1491:                    try {
1492:                        // Do no use File.toURI to avoid file system access
1493:                        String path = f.getAbsolutePath().replace(
1494:                                File.separatorChar, '/');
1495:                        return new URI("file://" + path).normalize();
1496:                    } catch (URISyntaxException ex) {
1497:                        return f.toURI();
1498:                    }
1499:                }
1500:
1501:            }
1502:
1503:            /**
1504:             * A subclass of JavaFileObject representing zip entries.
1505:             */
1506:            public class ZipFileObject extends BaseFileObject {
1507:
1508:                /** The entry's name.
1509:                 */
1510:                private String name;
1511:
1512:                /** The zipfile containing the entry.
1513:                 */
1514:                ZipFile zdir;
1515:
1516:                /** The underlying zip entry object.
1517:                 */
1518:                ZipEntry entry;
1519:
1520:                public ZipFileObject(String name, ZipFile zdir, ZipEntry entry) {
1521:                    this .name = name;
1522:                    this .zdir = zdir;
1523:                    this .entry = entry;
1524:                }
1525:
1526:                public InputStream openInputStream() throws IOException {
1527:                    return zdir.getInputStream(entry);
1528:                }
1529:
1530:                public OutputStream openOutputStream() throws IOException {
1531:                    throw new UnsupportedOperationException();
1532:                }
1533:
1534:                protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
1535:                    return JavacFileManager.this .getDecoder(getEncodingName(),
1536:                            ignoreEncodingErrors);
1537:                }
1538:
1539:                public Writer openWriter() throws IOException {
1540:                    throw new UnsupportedOperationException();
1541:                }
1542:
1543:                /** @deprecated see bug 6410637 */
1544:                @Deprecated
1545:                public String getName() {
1546:                    return name;
1547:                }
1548:
1549:                public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
1550:                    cn.getClass(); // null check
1551:                    if (k == Kind.OTHER && getKind() != k)
1552:                        return false;
1553:                    return name.equals(cn + k.extension);
1554:                }
1555:
1556:                /** @deprecated see bug 6410637 */
1557:                @Deprecated
1558:                public String getPath() {
1559:                    return zdir.getName() + "(" + entry + ")";
1560:                }
1561:
1562:                public long getLastModified() {
1563:                    return entry.getTime();
1564:                }
1565:
1566:                public boolean delete() {
1567:                    throw new UnsupportedOperationException();
1568:                }
1569:
1570:                public CharBuffer getCharContent(boolean ignoreEncodingErrors)
1571:                        throws IOException {
1572:                    SoftReference<CharBuffer> r = contentCache.get(this );
1573:                    CharBuffer cb = (r == null ? null : r.get());
1574:                    if (cb == null) {
1575:                        InputStream in = zdir.getInputStream(entry);
1576:                        try {
1577:                            ByteBuffer bb = makeByteBuffer(in);
1578:                            JavaFileObject prev = log.useSource(this );
1579:                            try {
1580:                                cb = decode(bb, ignoreEncodingErrors);
1581:                            } finally {
1582:                                log.useSource(prev);
1583:                            }
1584:                            byteBufferCache.put(bb); // save for next time
1585:                            if (!ignoreEncodingErrors)
1586:                                contentCache.put(this ,
1587:                                        new SoftReference<CharBuffer>(cb));
1588:                        } finally {
1589:                            in.close();
1590:                        }
1591:                    }
1592:                    return cb;
1593:                }
1594:
1595:                @Override
1596:                public boolean equals(Object other) {
1597:                    if (!(other instanceof  ZipFileObject))
1598:                        return false;
1599:                    ZipFileObject o = (ZipFileObject) other;
1600:                    return zdir.equals(o.zdir) || name.equals(o.name);
1601:                }
1602:
1603:                @Override
1604:                public int hashCode() {
1605:                    return zdir.hashCode() + name.hashCode();
1606:                }
1607:
1608:                public String getZipName() {
1609:                    return zdir.getName();
1610:                }
1611:
1612:                public String getZipEntryName() {
1613:                    return entry.getName();
1614:                }
1615:
1616:                public URI toUri() {
1617:                    String zipName = new File(getZipName()).toURI().normalize()
1618:                            .getPath();
1619:                    String entryName = getZipEntryName();
1620:                    return URI.create("jar:" + zipName + "!" + entryName);
1621:                }
1622:
1623:            }
1624:
1625:            /**
1626:             * A subclass of JavaFileObject representing zip entries using the com.sun.tools.javac.zip.ZipFileIndex implementation.
1627:             */
1628:            public class ZipFileIndexFileObject extends BaseFileObject {
1629:
1630:                /** The entry's name.
1631:                 */
1632:                private String name;
1633:
1634:                /** The zipfile containing the entry.
1635:                 */
1636:                ZipFileIndex zfIndex;
1637:
1638:                /** The underlying zip entry object.
1639:                 */
1640:                ZipFileIndexEntry entry;
1641:
1642:                /** The InputStream for this zip entry (file.)
1643:                 */
1644:                InputStream inputStream = null;
1645:
1646:                /** The name of the zip file where this entry resides.
1647:                 */
1648:                String zipName;
1649:
1650:                JavacFileManager defFileManager = null;
1651:
1652:                public ZipFileIndexFileObject(JavacFileManager fileManager,
1653:                        ZipFileIndex zfIndex, ZipFileIndexEntry entry,
1654:                        String zipFileName) {
1655:                    super ();
1656:                    this .name = entry.getFileName();
1657:                    this .zfIndex = zfIndex;
1658:                    this .entry = entry;
1659:                    this .zipName = zipFileName;
1660:                    defFileManager = fileManager;
1661:                }
1662:
1663:                public InputStream openInputStream() throws IOException {
1664:
1665:                    if (inputStream == null) {
1666:                        inputStream = new ByteArrayInputStream(read());
1667:                    }
1668:                    return inputStream;
1669:                }
1670:
1671:                protected CharsetDecoder getDecoder(boolean ignoreEncodingErrors) {
1672:                    return JavacFileManager.this .getDecoder(getEncodingName(),
1673:                            ignoreEncodingErrors);
1674:                }
1675:
1676:                public OutputStream openOutputStream() throws IOException {
1677:                    throw new UnsupportedOperationException();
1678:                }
1679:
1680:                public Writer openWriter() throws IOException {
1681:                    throw new UnsupportedOperationException();
1682:                }
1683:
1684:                /** @deprecated see bug 6410637 */
1685:                @Deprecated
1686:                public String getName() {
1687:                    return name;
1688:                }
1689:
1690:                public boolean isNameCompatible(String cn, JavaFileObject.Kind k) {
1691:                    cn.getClass(); // null check
1692:                    if (k == Kind.OTHER && getKind() != k)
1693:                        return false;
1694:                    return name.equals(cn + k.extension);
1695:                }
1696:
1697:                /** @deprecated see bug 6410637 */
1698:                @Deprecated
1699:                public String getPath() {
1700:                    return entry.getName() + "(" + entry + ")";
1701:                }
1702:
1703:                public long getLastModified() {
1704:                    return entry.getLastModified();
1705:                }
1706:
1707:                public boolean delete() {
1708:                    throw new UnsupportedOperationException();
1709:                }
1710:
1711:                @Override
1712:                public boolean equals(Object other) {
1713:                    if (!(other instanceof  ZipFileIndexFileObject))
1714:                        return false;
1715:                    ZipFileIndexFileObject o = (ZipFileIndexFileObject) other;
1716:                    return entry.equals(o.entry);
1717:                }
1718:
1719:                @Override
1720:                public int hashCode() {
1721:                    return zipName.hashCode() + (name.hashCode() << 10);
1722:                }
1723:
1724:                public String getZipName() {
1725:                    return zipName;
1726:                }
1727:
1728:                public String getZipEntryName() {
1729:                    return entry.getName();
1730:                }
1731:
1732:                public URI toUri() {
1733:                    String zipName = new File(getZipName()).toURI().normalize()
1734:                            .getPath();
1735:                    String entryName = getZipEntryName();
1736:                    if (File.separatorChar != '/') {
1737:                        entryName = entryName.replace(File.separatorChar, '/');
1738:                    }
1739:                    return URI.create("jar:" + zipName + "!" + entryName);
1740:                }
1741:
1742:                private byte[] read() throws IOException {
1743:                    if (entry == null) {
1744:                        entry = zfIndex.getZipIndexEntry(name);
1745:                        if (entry == null)
1746:                            throw new FileNotFoundException();
1747:                    }
1748:                    return zfIndex.read(entry);
1749:                }
1750:
1751:                public CharBuffer getCharContent(boolean ignoreEncodingErrors)
1752:                        throws IOException {
1753:                    SoftReference<CharBuffer> r = defFileManager.contentCache
1754:                            .get(this );
1755:                    CharBuffer cb = (r == null ? null : r.get());
1756:                    if (cb == null) {
1757:                        InputStream in = new ByteArrayInputStream(zfIndex
1758:                                .read(entry));
1759:                        try {
1760:                            ByteBuffer bb = makeByteBuffer(in);
1761:                            JavaFileObject prev = log.useSource(this );
1762:                            try {
1763:                                cb = decode(bb, ignoreEncodingErrors);
1764:                            } finally {
1765:                                log.useSource(prev);
1766:                            }
1767:                            byteBufferCache.put(bb); // save for next time
1768:                            if (!ignoreEncodingErrors)
1769:                                defFileManager.contentCache.put(this ,
1770:                                        new SoftReference<CharBuffer>(cb));
1771:                        } finally {
1772:                            in.close();
1773:                        }
1774:                    }
1775:                    return cb;
1776:                }
1777:            }
1778:
1779:            public class ZipFileIndexArchive implements  Archive {
1780:                private final ZipFileIndex zfIndex;
1781:                private JavacFileManager fileManager;
1782:
1783:                public ZipFileIndexArchive(JavacFileManager fileManager,
1784:                        ZipFileIndex zdir) throws IOException {
1785:                    this .fileManager = fileManager;
1786:                    this .zfIndex = zdir;
1787:                }
1788:
1789:                public boolean contains(String name) {
1790:                    return zfIndex.contains(name);
1791:                }
1792:
1793:                public com.sun.tools.javac.util.List<String> getFiles(
1794:                        String subdirectory) {
1795:                    return zfIndex
1796:                            .getFiles(((subdirectory.endsWith("/") || subdirectory
1797:                                    .endsWith("\\")) ? subdirectory.substring(
1798:                                    0, subdirectory.length() - 1)
1799:                                    : subdirectory));
1800:                }
1801:
1802:                public JavaFileObject getFileObject(String subdirectory,
1803:                        String file) {
1804:                    String fullZipFileName = subdirectory + file;
1805:                    ZipFileIndexEntry entry = zfIndex
1806:                            .getZipIndexEntry(fullZipFileName);
1807:                    JavaFileObject ret = new ZipFileIndexFileObject(
1808:                            fileManager, zfIndex, entry, zfIndex.getZipFile()
1809:                                    .getPath());
1810:                    return ret;
1811:                }
1812:
1813:                public Set<String> getSubdirectories() {
1814:                    return zfIndex.getAllDirectories();
1815:                }
1816:
1817:                public void close() throws IOException {
1818:                    zfIndex.close();
1819:                }
1820:            }
1821:        }
www.java2java.com | Contact Us
Copyright 2009 - 12 Demo Source and Support. All rights reserved.
All other trademarks are property of their respective owners.