src/share/classes/com/sun/tools/javac/nio/JavacPathFileManager.java

Thu, 31 Aug 2017 15:17:03 +0800

author
aoqi
date
Thu, 31 Aug 2017 15:17:03 +0800
changeset 2525
2eb010b6cb22
parent 1413
bdcef2ef52d2
parent 0
959103a6100f
permissions
-rw-r--r--

merge

aoqi@0 1 /*
aoqi@0 2 * Copyright (c) 2009, 2012, Oracle and/or its affiliates. All rights reserved.
aoqi@0 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
aoqi@0 4 *
aoqi@0 5 * This code is free software; you can redistribute it and/or modify it
aoqi@0 6 * under the terms of the GNU General Public License version 2 only, as
aoqi@0 7 * published by the Free Software Foundation. Oracle designates this
aoqi@0 8 * particular file as subject to the "Classpath" exception as provided
aoqi@0 9 * by Oracle in the LICENSE file that accompanied this code.
aoqi@0 10 *
aoqi@0 11 * This code is distributed in the hope that it will be useful, but WITHOUT
aoqi@0 12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
aoqi@0 13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
aoqi@0 14 * version 2 for more details (a copy is included in the LICENSE file that
aoqi@0 15 * accompanied this code).
aoqi@0 16 *
aoqi@0 17 * You should have received a copy of the GNU General Public License version
aoqi@0 18 * 2 along with this work; if not, write to the Free Software Foundation,
aoqi@0 19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
aoqi@0 20 *
aoqi@0 21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
aoqi@0 22 * or visit www.oracle.com if you need additional information or have any
aoqi@0 23 * questions.
aoqi@0 24 */
aoqi@0 25
aoqi@0 26 package com.sun.tools.javac.nio;
aoqi@0 27
aoqi@0 28 import java.io.File;
aoqi@0 29 import java.io.IOException;
aoqi@0 30 import java.net.MalformedURLException;
aoqi@0 31 import java.net.URL;
aoqi@0 32 import java.nio.charset.Charset;
aoqi@0 33 import java.nio.file.Files;
aoqi@0 34 import java.nio.file.FileSystem;
aoqi@0 35 import java.nio.file.FileSystems;
aoqi@0 36 import java.nio.file.FileVisitOption;
aoqi@0 37 import java.nio.file.FileVisitResult;
aoqi@0 38 import java.nio.file.Path;
aoqi@0 39 import java.nio.file.SimpleFileVisitor;
aoqi@0 40 import java.nio.file.attribute.BasicFileAttributes;
aoqi@0 41 import java.util.ArrayList;
aoqi@0 42 import java.util.Arrays;
aoqi@0 43 import java.util.Collection;
aoqi@0 44 import java.util.Collections;
aoqi@0 45 import java.util.EnumSet;
aoqi@0 46 import java.util.HashMap;
aoqi@0 47 import java.util.Iterator;
aoqi@0 48 import java.util.LinkedHashSet;
aoqi@0 49 import java.util.Map;
aoqi@0 50 import java.util.Set;
aoqi@0 51 import javax.lang.model.SourceVersion;
aoqi@0 52 import javax.tools.FileObject;
aoqi@0 53 import javax.tools.JavaFileManager;
aoqi@0 54 import javax.tools.JavaFileObject;
aoqi@0 55 import javax.tools.JavaFileObject.Kind;
aoqi@0 56 import javax.tools.StandardLocation;
aoqi@0 57
aoqi@0 58 import static java.nio.file.FileVisitOption.*;
aoqi@0 59 import static javax.tools.StandardLocation.*;
aoqi@0 60
aoqi@0 61 import com.sun.tools.javac.util.BaseFileManager;
aoqi@0 62 import com.sun.tools.javac.util.Context;
aoqi@0 63 import com.sun.tools.javac.util.List;
aoqi@0 64 import com.sun.tools.javac.util.ListBuffer;
aoqi@0 65
aoqi@0 66 import static com.sun.tools.javac.main.Option.*;
aoqi@0 67
aoqi@0 68
aoqi@0 69 // NOTE the imports carefully for this compilation unit.
aoqi@0 70 //
aoqi@0 71 // Path: java.nio.file.Path -- the new NIO type for which this file manager exists
aoqi@0 72 //
aoqi@0 73 // Paths: com.sun.tools.javac.file.Paths -- legacy javac type for handling path options
aoqi@0 74 // The other Paths (java.nio.file.Paths) is not used
aoqi@0 75
aoqi@0 76 // NOTE this and related classes depend on new API in JDK 7.
aoqi@0 77 // This requires special handling while bootstrapping the JDK build,
aoqi@0 78 // when these classes might not yet have been compiled. To workaround
aoqi@0 79 // this, the build arranges to make stubs of these classes available
aoqi@0 80 // when compiling this and related classes. The set of stub files
aoqi@0 81 // is specified in make/build.properties.
aoqi@0 82
aoqi@0 83 /**
aoqi@0 84 * Implementation of PathFileManager: a JavaFileManager based on the use
aoqi@0 85 * of java.nio.file.Path.
aoqi@0 86 *
aoqi@0 87 * <p>Just as a Path is somewhat analagous to a File, so too is this
aoqi@0 88 * JavacPathFileManager analogous to JavacFileManager, as it relates to the
aoqi@0 89 * support of FileObjects based on File objects (i.e. just RegularFileObject,
aoqi@0 90 * not ZipFileObject and its variants.)
aoqi@0 91 *
aoqi@0 92 * <p>The default values for the standard locations supported by this file
aoqi@0 93 * manager are the same as the default values provided by JavacFileManager --
aoqi@0 94 * i.e. as determined by the javac.file.Paths class. To override these values,
aoqi@0 95 * call {@link #setLocation}.
aoqi@0 96 *
aoqi@0 97 * <p>To reduce confusion with Path objects, the locations such as "class path",
aoqi@0 98 * "source path", etc, are generically referred to here as "search paths".
aoqi@0 99 *
aoqi@0 100 * <p><b>This is NOT part of any supported API.
aoqi@0 101 * If you write code that depends on this, you do so at your own risk.
aoqi@0 102 * This code and its internal interfaces are subject to change or
aoqi@0 103 * deletion without notice.</b>
aoqi@0 104 */
aoqi@0 105 public class JavacPathFileManager extends BaseFileManager implements PathFileManager {
aoqi@0 106 protected FileSystem defaultFileSystem;
aoqi@0 107
aoqi@0 108 /**
aoqi@0 109 * Create a JavacPathFileManager using a given context, optionally registering
aoqi@0 110 * it as the JavaFileManager for that context.
aoqi@0 111 */
aoqi@0 112 public JavacPathFileManager(Context context, boolean register, Charset charset) {
aoqi@0 113 super(charset);
aoqi@0 114 if (register)
aoqi@0 115 context.put(JavaFileManager.class, this);
aoqi@0 116 pathsForLocation = new HashMap<Location, PathsForLocation>();
aoqi@0 117 fileSystems = new HashMap<Path,FileSystem>();
aoqi@0 118 setContext(context);
aoqi@0 119 }
aoqi@0 120
aoqi@0 121 /**
aoqi@0 122 * Set the context for JavacPathFileManager.
aoqi@0 123 */
aoqi@0 124 @Override
aoqi@0 125 public void setContext(Context context) {
aoqi@0 126 super.setContext(context);
aoqi@0 127 }
aoqi@0 128
aoqi@0 129 @Override
aoqi@0 130 public FileSystem getDefaultFileSystem() {
aoqi@0 131 if (defaultFileSystem == null)
aoqi@0 132 defaultFileSystem = FileSystems.getDefault();
aoqi@0 133 return defaultFileSystem;
aoqi@0 134 }
aoqi@0 135
aoqi@0 136 @Override
aoqi@0 137 public void setDefaultFileSystem(FileSystem fs) {
aoqi@0 138 defaultFileSystem = fs;
aoqi@0 139 }
aoqi@0 140
aoqi@0 141 @Override
aoqi@0 142 public void flush() throws IOException {
aoqi@0 143 contentCache.clear();
aoqi@0 144 }
aoqi@0 145
aoqi@0 146 @Override
aoqi@0 147 public void close() throws IOException {
aoqi@0 148 for (FileSystem fs: fileSystems.values())
aoqi@0 149 fs.close();
aoqi@0 150 }
aoqi@0 151
aoqi@0 152 @Override
aoqi@0 153 public ClassLoader getClassLoader(Location location) {
aoqi@0 154 nullCheck(location);
aoqi@0 155 Iterable<? extends Path> path = getLocation(location);
aoqi@0 156 if (path == null)
aoqi@0 157 return null;
aoqi@0 158 ListBuffer<URL> lb = new ListBuffer<URL>();
aoqi@0 159 for (Path p: path) {
aoqi@0 160 try {
aoqi@0 161 lb.append(p.toUri().toURL());
aoqi@0 162 } catch (MalformedURLException e) {
aoqi@0 163 throw new AssertionError(e);
aoqi@0 164 }
aoqi@0 165 }
aoqi@0 166
aoqi@0 167 return getClassLoader(lb.toArray(new URL[lb.size()]));
aoqi@0 168 }
aoqi@0 169
aoqi@0 170 @Override
aoqi@0 171 public boolean isDefaultBootClassPath() {
aoqi@0 172 return locations.isDefaultBootClassPath();
aoqi@0 173 }
aoqi@0 174
aoqi@0 175 // <editor-fold defaultstate="collapsed" desc="Location handling">
aoqi@0 176
aoqi@0 177 public boolean hasLocation(Location location) {
aoqi@0 178 return (getLocation(location) != null);
aoqi@0 179 }
aoqi@0 180
aoqi@0 181 public Iterable<? extends Path> getLocation(Location location) {
aoqi@0 182 nullCheck(location);
aoqi@0 183 lazyInitSearchPaths();
aoqi@0 184 PathsForLocation path = pathsForLocation.get(location);
aoqi@0 185 if (path == null && !pathsForLocation.containsKey(location)) {
aoqi@0 186 setDefaultForLocation(location);
aoqi@0 187 path = pathsForLocation.get(location);
aoqi@0 188 }
aoqi@0 189 return path;
aoqi@0 190 }
aoqi@0 191
aoqi@0 192 private Path getOutputLocation(Location location) {
aoqi@0 193 Iterable<? extends Path> paths = getLocation(location);
aoqi@0 194 return (paths == null ? null : paths.iterator().next());
aoqi@0 195 }
aoqi@0 196
aoqi@0 197 public void setLocation(Location location, Iterable<? extends Path> searchPath)
aoqi@0 198 throws IOException
aoqi@0 199 {
aoqi@0 200 nullCheck(location);
aoqi@0 201 lazyInitSearchPaths();
aoqi@0 202 if (searchPath == null) {
aoqi@0 203 setDefaultForLocation(location);
aoqi@0 204 } else {
aoqi@0 205 if (location.isOutputLocation())
aoqi@0 206 checkOutputPath(searchPath);
aoqi@0 207 PathsForLocation pl = new PathsForLocation();
aoqi@0 208 for (Path p: searchPath)
aoqi@0 209 pl.add(p); // TODO -Xlint:path warn if path not found
aoqi@0 210 pathsForLocation.put(location, pl);
aoqi@0 211 }
aoqi@0 212 }
aoqi@0 213
aoqi@0 214 private void checkOutputPath(Iterable<? extends Path> searchPath) throws IOException {
aoqi@0 215 Iterator<? extends Path> pathIter = searchPath.iterator();
aoqi@0 216 if (!pathIter.hasNext())
aoqi@0 217 throw new IllegalArgumentException("empty path for directory");
aoqi@0 218 Path path = pathIter.next();
aoqi@0 219 if (pathIter.hasNext())
aoqi@0 220 throw new IllegalArgumentException("path too long for directory");
aoqi@0 221 if (!isDirectory(path))
aoqi@0 222 throw new IOException(path + ": not a directory");
aoqi@0 223 }
aoqi@0 224
aoqi@0 225 private void setDefaultForLocation(Location locn) {
aoqi@0 226 Collection<File> files = null;
aoqi@0 227 if (locn instanceof StandardLocation) {
aoqi@0 228 switch ((StandardLocation) locn) {
aoqi@0 229 case CLASS_PATH:
aoqi@0 230 files = locations.userClassPath();
aoqi@0 231 break;
aoqi@0 232 case PLATFORM_CLASS_PATH:
aoqi@0 233 files = locations.bootClassPath();
aoqi@0 234 break;
aoqi@0 235 case SOURCE_PATH:
aoqi@0 236 files = locations.sourcePath();
aoqi@0 237 break;
aoqi@0 238 case CLASS_OUTPUT: {
aoqi@0 239 String arg = options.get(D);
aoqi@0 240 files = (arg == null ? null : Collections.singleton(new File(arg)));
aoqi@0 241 break;
aoqi@0 242 }
aoqi@0 243 case SOURCE_OUTPUT: {
aoqi@0 244 String arg = options.get(S);
aoqi@0 245 files = (arg == null ? null : Collections.singleton(new File(arg)));
aoqi@0 246 break;
aoqi@0 247 }
aoqi@0 248 }
aoqi@0 249 }
aoqi@0 250
aoqi@0 251 PathsForLocation pl = new PathsForLocation();
aoqi@0 252 if (files != null) {
aoqi@0 253 for (File f: files)
aoqi@0 254 pl.add(f.toPath());
aoqi@0 255 }
aoqi@0 256 if (!pl.isEmpty())
aoqi@0 257 pathsForLocation.put(locn, pl);
aoqi@0 258 }
aoqi@0 259
aoqi@0 260 private void lazyInitSearchPaths() {
aoqi@0 261 if (!inited) {
aoqi@0 262 setDefaultForLocation(PLATFORM_CLASS_PATH);
aoqi@0 263 setDefaultForLocation(CLASS_PATH);
aoqi@0 264 setDefaultForLocation(SOURCE_PATH);
aoqi@0 265 inited = true;
aoqi@0 266 }
aoqi@0 267 }
aoqi@0 268 // where
aoqi@0 269 private boolean inited = false;
aoqi@0 270
aoqi@0 271 private Map<Location, PathsForLocation> pathsForLocation;
aoqi@0 272
aoqi@0 273 private static class PathsForLocation extends LinkedHashSet<Path> {
aoqi@0 274 private static final long serialVersionUID = 6788510222394486733L;
aoqi@0 275 }
aoqi@0 276
aoqi@0 277 // </editor-fold>
aoqi@0 278
aoqi@0 279 // <editor-fold defaultstate="collapsed" desc="FileObject handling">
aoqi@0 280
aoqi@0 281 @Override
aoqi@0 282 public Path getPath(FileObject fo) {
aoqi@0 283 nullCheck(fo);
aoqi@0 284 if (!(fo instanceof PathFileObject))
aoqi@0 285 throw new IllegalArgumentException();
aoqi@0 286 return ((PathFileObject) fo).getPath();
aoqi@0 287 }
aoqi@0 288
aoqi@0 289 @Override
aoqi@0 290 public boolean isSameFile(FileObject a, FileObject b) {
aoqi@0 291 nullCheck(a);
aoqi@0 292 nullCheck(b);
aoqi@0 293 if (!(a instanceof PathFileObject))
aoqi@0 294 throw new IllegalArgumentException("Not supported: " + a);
aoqi@0 295 if (!(b instanceof PathFileObject))
aoqi@0 296 throw new IllegalArgumentException("Not supported: " + b);
aoqi@0 297 return ((PathFileObject) a).isSameFile((PathFileObject) b);
aoqi@0 298 }
aoqi@0 299
aoqi@0 300 @Override
aoqi@0 301 public Iterable<JavaFileObject> list(Location location,
aoqi@0 302 String packageName, Set<Kind> kinds, boolean recurse)
aoqi@0 303 throws IOException {
aoqi@0 304 // validatePackageName(packageName);
aoqi@0 305 nullCheck(packageName);
aoqi@0 306 nullCheck(kinds);
aoqi@0 307
aoqi@0 308 Iterable<? extends Path> paths = getLocation(location);
aoqi@0 309 if (paths == null)
aoqi@0 310 return List.nil();
aoqi@0 311 ListBuffer<JavaFileObject> results = new ListBuffer<JavaFileObject>();
aoqi@0 312
aoqi@0 313 for (Path path : paths)
aoqi@0 314 list(path, packageName, kinds, recurse, results);
aoqi@0 315
aoqi@0 316 return results.toList();
aoqi@0 317 }
aoqi@0 318
aoqi@0 319 private void list(Path path, String packageName, final Set<Kind> kinds,
aoqi@0 320 boolean recurse, final ListBuffer<JavaFileObject> results)
aoqi@0 321 throws IOException {
aoqi@0 322 if (!Files.exists(path))
aoqi@0 323 return;
aoqi@0 324
aoqi@0 325 final Path pathDir;
aoqi@0 326 if (isDirectory(path))
aoqi@0 327 pathDir = path;
aoqi@0 328 else {
aoqi@0 329 FileSystem fs = getFileSystem(path);
aoqi@0 330 if (fs == null)
aoqi@0 331 return;
aoqi@0 332 pathDir = fs.getRootDirectories().iterator().next();
aoqi@0 333 }
aoqi@0 334 String sep = path.getFileSystem().getSeparator();
aoqi@0 335 Path packageDir = packageName.isEmpty() ? pathDir
aoqi@0 336 : pathDir.resolve(packageName.replace(".", sep));
aoqi@0 337 if (!Files.exists(packageDir))
aoqi@0 338 return;
aoqi@0 339
aoqi@0 340 /* Alternate impl of list, superceded by use of Files.walkFileTree */
aoqi@0 341 // Deque<Path> queue = new LinkedList<Path>();
aoqi@0 342 // queue.add(packageDir);
aoqi@0 343 //
aoqi@0 344 // Path dir;
aoqi@0 345 // while ((dir = queue.poll()) != null) {
aoqi@0 346 // DirectoryStream<Path> ds = dir.newDirectoryStream();
aoqi@0 347 // try {
aoqi@0 348 // for (Path p: ds) {
aoqi@0 349 // String name = p.getFileName().toString();
aoqi@0 350 // if (isDirectory(p)) {
aoqi@0 351 // if (recurse && SourceVersion.isIdentifier(name)) {
aoqi@0 352 // queue.add(p);
aoqi@0 353 // }
aoqi@0 354 // } else {
aoqi@0 355 // if (kinds.contains(getKind(name))) {
aoqi@0 356 // JavaFileObject fe =
aoqi@0 357 // PathFileObject.createDirectoryPathFileObject(this, p, pathDir);
aoqi@0 358 // results.append(fe);
aoqi@0 359 // }
aoqi@0 360 // }
aoqi@0 361 // }
aoqi@0 362 // } finally {
aoqi@0 363 // ds.close();
aoqi@0 364 // }
aoqi@0 365 // }
aoqi@0 366 int maxDepth = (recurse ? Integer.MAX_VALUE : 1);
aoqi@0 367 Set<FileVisitOption> opts = EnumSet.of(FOLLOW_LINKS);
aoqi@0 368 Files.walkFileTree(packageDir, opts, maxDepth,
aoqi@0 369 new SimpleFileVisitor<Path>() {
aoqi@0 370 @Override
aoqi@0 371 public FileVisitResult preVisitDirectory(Path dir, BasicFileAttributes attrs) {
aoqi@0 372 Path name = dir.getFileName();
aoqi@0 373 if (name == null || SourceVersion.isIdentifier(name.toString())) // JSR 292?
aoqi@0 374 return FileVisitResult.CONTINUE;
aoqi@0 375 else
aoqi@0 376 return FileVisitResult.SKIP_SUBTREE;
aoqi@0 377 }
aoqi@0 378
aoqi@0 379 @Override
aoqi@0 380 public FileVisitResult visitFile(Path file, BasicFileAttributes attrs) {
aoqi@0 381 if (attrs.isRegularFile() && kinds.contains(getKind(file.getFileName().toString()))) {
aoqi@0 382 JavaFileObject fe =
aoqi@0 383 PathFileObject.createDirectoryPathFileObject(
aoqi@0 384 JavacPathFileManager.this, file, pathDir);
aoqi@0 385 results.append(fe);
aoqi@0 386 }
aoqi@0 387 return FileVisitResult.CONTINUE;
aoqi@0 388 }
aoqi@0 389 });
aoqi@0 390 }
aoqi@0 391
aoqi@0 392 @Override
aoqi@0 393 public Iterable<? extends JavaFileObject> getJavaFileObjectsFromPaths(
aoqi@0 394 Iterable<? extends Path> paths) {
aoqi@0 395 ArrayList<PathFileObject> result;
aoqi@0 396 if (paths instanceof Collection<?>)
aoqi@0 397 result = new ArrayList<PathFileObject>(((Collection<?>)paths).size());
aoqi@0 398 else
aoqi@0 399 result = new ArrayList<PathFileObject>();
aoqi@0 400 for (Path p: paths)
aoqi@0 401 result.add(PathFileObject.createSimplePathFileObject(this, nullCheck(p)));
aoqi@0 402 return result;
aoqi@0 403 }
aoqi@0 404
aoqi@0 405 @Override
aoqi@0 406 public Iterable<? extends JavaFileObject> getJavaFileObjects(Path... paths) {
aoqi@0 407 return getJavaFileObjectsFromPaths(Arrays.asList(nullCheck(paths)));
aoqi@0 408 }
aoqi@0 409
aoqi@0 410 @Override
aoqi@0 411 public JavaFileObject getJavaFileForInput(Location location,
aoqi@0 412 String className, Kind kind) throws IOException {
aoqi@0 413 return getFileForInput(location, getRelativePath(className, kind));
aoqi@0 414 }
aoqi@0 415
aoqi@0 416 @Override
aoqi@0 417 public FileObject getFileForInput(Location location,
aoqi@0 418 String packageName, String relativeName) throws IOException {
aoqi@0 419 return getFileForInput(location, getRelativePath(packageName, relativeName));
aoqi@0 420 }
aoqi@0 421
aoqi@0 422 private JavaFileObject getFileForInput(Location location, String relativePath)
aoqi@0 423 throws IOException {
aoqi@0 424 for (Path p: getLocation(location)) {
aoqi@0 425 if (isDirectory(p)) {
aoqi@0 426 Path f = resolve(p, relativePath);
aoqi@0 427 if (Files.exists(f))
aoqi@0 428 return PathFileObject.createDirectoryPathFileObject(this, f, p);
aoqi@0 429 } else {
aoqi@0 430 FileSystem fs = getFileSystem(p);
aoqi@0 431 if (fs != null) {
aoqi@0 432 Path file = getPath(fs, relativePath);
aoqi@0 433 if (Files.exists(file))
aoqi@0 434 return PathFileObject.createJarPathFileObject(this, file);
aoqi@0 435 }
aoqi@0 436 }
aoqi@0 437 }
aoqi@0 438 return null;
aoqi@0 439 }
aoqi@0 440
aoqi@0 441 @Override
aoqi@0 442 public JavaFileObject getJavaFileForOutput(Location location,
aoqi@0 443 String className, Kind kind, FileObject sibling) throws IOException {
aoqi@0 444 return getFileForOutput(location, getRelativePath(className, kind), sibling);
aoqi@0 445 }
aoqi@0 446
aoqi@0 447 @Override
aoqi@0 448 public FileObject getFileForOutput(Location location, String packageName,
aoqi@0 449 String relativeName, FileObject sibling)
aoqi@0 450 throws IOException {
aoqi@0 451 return getFileForOutput(location, getRelativePath(packageName, relativeName), sibling);
aoqi@0 452 }
aoqi@0 453
aoqi@0 454 private JavaFileObject getFileForOutput(Location location,
aoqi@0 455 String relativePath, FileObject sibling) {
aoqi@0 456 Path dir = getOutputLocation(location);
aoqi@0 457 if (dir == null) {
aoqi@0 458 if (location == CLASS_OUTPUT) {
aoqi@0 459 Path siblingDir = null;
aoqi@0 460 if (sibling != null && sibling instanceof PathFileObject) {
aoqi@0 461 siblingDir = ((PathFileObject) sibling).getPath().getParent();
aoqi@0 462 }
aoqi@0 463 return PathFileObject.createSiblingPathFileObject(this,
aoqi@0 464 siblingDir.resolve(getBaseName(relativePath)),
aoqi@0 465 relativePath);
aoqi@0 466 } else if (location == SOURCE_OUTPUT) {
aoqi@0 467 dir = getOutputLocation(CLASS_OUTPUT);
aoqi@0 468 }
aoqi@0 469 }
aoqi@0 470
aoqi@0 471 Path file;
aoqi@0 472 if (dir != null) {
aoqi@0 473 file = resolve(dir, relativePath);
aoqi@0 474 return PathFileObject.createDirectoryPathFileObject(this, file, dir);
aoqi@0 475 } else {
aoqi@0 476 file = getPath(getDefaultFileSystem(), relativePath);
aoqi@0 477 return PathFileObject.createSimplePathFileObject(this, file);
aoqi@0 478 }
aoqi@0 479
aoqi@0 480 }
aoqi@0 481
aoqi@0 482 @Override
aoqi@0 483 public String inferBinaryName(Location location, JavaFileObject fo) {
aoqi@0 484 nullCheck(fo);
aoqi@0 485 // Need to match the path semantics of list(location, ...)
aoqi@0 486 Iterable<? extends Path> paths = getLocation(location);
aoqi@0 487 if (paths == null) {
aoqi@0 488 return null;
aoqi@0 489 }
aoqi@0 490
aoqi@0 491 if (!(fo instanceof PathFileObject))
aoqi@0 492 throw new IllegalArgumentException(fo.getClass().getName());
aoqi@0 493
aoqi@0 494 return ((PathFileObject) fo).inferBinaryName(paths);
aoqi@0 495 }
aoqi@0 496
aoqi@0 497 private FileSystem getFileSystem(Path p) throws IOException {
aoqi@0 498 FileSystem fs = fileSystems.get(p);
aoqi@0 499 if (fs == null) {
aoqi@0 500 fs = FileSystems.newFileSystem(p, null);
aoqi@0 501 fileSystems.put(p, fs);
aoqi@0 502 }
aoqi@0 503 return fs;
aoqi@0 504 }
aoqi@0 505
aoqi@0 506 private Map<Path,FileSystem> fileSystems;
aoqi@0 507
aoqi@0 508 // </editor-fold>
aoqi@0 509
aoqi@0 510 // <editor-fold defaultstate="collapsed" desc="Utility methods">
aoqi@0 511
aoqi@0 512 private static String getRelativePath(String className, Kind kind) {
aoqi@0 513 return className.replace(".", "/") + kind.extension;
aoqi@0 514 }
aoqi@0 515
aoqi@0 516 private static String getRelativePath(String packageName, String relativeName) {
aoqi@0 517 return packageName.isEmpty()
aoqi@0 518 ? relativeName : packageName.replace(".", "/") + "/" + relativeName;
aoqi@0 519 }
aoqi@0 520
aoqi@0 521 private static String getBaseName(String relativePath) {
aoqi@0 522 int lastSep = relativePath.lastIndexOf("/");
aoqi@0 523 return relativePath.substring(lastSep + 1); // safe if "/" not found
aoqi@0 524 }
aoqi@0 525
aoqi@0 526 private static boolean isDirectory(Path path) throws IOException {
aoqi@0 527 BasicFileAttributes attrs = Files.readAttributes(path, BasicFileAttributes.class);
aoqi@0 528 return attrs.isDirectory();
aoqi@0 529 }
aoqi@0 530
aoqi@0 531 private static Path getPath(FileSystem fs, String relativePath) {
aoqi@0 532 return fs.getPath(relativePath.replace("/", fs.getSeparator()));
aoqi@0 533 }
aoqi@0 534
aoqi@0 535 private static Path resolve(Path base, String relativePath) {
aoqi@0 536 FileSystem fs = base.getFileSystem();
aoqi@0 537 Path rp = fs.getPath(relativePath.replace("/", fs.getSeparator()));
aoqi@0 538 return base.resolve(rp);
aoqi@0 539 }
aoqi@0 540
aoqi@0 541 // </editor-fold>
aoqi@0 542
aoqi@0 543 }

mercurial