public boolean delete(Path path, boolean recursive) throws IOException {
   Path absolutePath = makeAbsolute(path);
   INode inode = store.retrieveINode(absolutePath);
   if (inode == null) {
     return false;
   }
   if (inode.isFile()) {
     store.deleteINode(absolutePath);
     for (Block block : inode.getBlocks()) {
       store.deleteBlock(block);
     }
   } else {
     FileStatus[] contents = listStatus(absolutePath);
     if (contents == null) {
       return false;
     }
     if ((contents.length != 0) && (!recursive)) {
       throw new IOException("Directory " + path.toString() + " is not empty.");
     }
     for (FileStatus p : contents) {
       if (!delete(p.getPath(), recursive)) {
         return false;
       }
     }
     store.deleteINode(absolutePath);
   }
   return true;
 }
 @Override
 public boolean rename(Path src, Path dst) throws IOException {
   Path absoluteSrc = makeAbsolute(src);
   INode srcINode = store.retrieveINode(absoluteSrc);
   if (srcINode == null) {
     // src path doesn't exist
     return false;
   }
   Path absoluteDst = makeAbsolute(dst);
   INode dstINode = store.retrieveINode(absoluteDst);
   if (dstINode != null && dstINode.isDirectory()) {
     absoluteDst = new Path(absoluteDst, absoluteSrc.getName());
     dstINode = store.retrieveINode(absoluteDst);
   }
   if (dstINode != null) {
     // dst path already exists - can't overwrite
     return false;
   }
   Path dstParent = absoluteDst.getParent();
   if (dstParent != null) {
     INode dstParentINode = store.retrieveINode(dstParent);
     if (dstParentINode == null || dstParentINode.isFile()) {
       // dst parent doesn't exist or is a file
       return false;
     }
   }
   return renameRecursive(absoluteSrc, absoluteDst);
 }
 private boolean mkdir(Path path) throws IOException {
   Path absolutePath = makeAbsolute(path);
   INode inode = store.retrieveINode(absolutePath);
   if (inode == null) {
     store.storeINode(absolutePath, INode.DIRECTORY_INODE);
   } else if (inode.isFile()) {
     throw new IOException(
         String.format("Can't make directory for path %s since it is a file.", absolutePath));
   }
   return true;
 }
 @Override
 public boolean isFile(Path path) throws IOException {
   INode inode = store.retrieveINode(makeAbsolute(path));
   if (inode == null) {
     return false;
   }
   return inode.isFile();
 }
 @Override
 public void initialize(URI uri, Configuration conf) throws IOException {
   super.initialize(uri, conf);
   if (store == null) {
     store = createDefaultStore(conf);
   }
   store.initialize(uri, conf);
   setConf(conf);
   this.uri = URI.create(uri.getScheme() + "://" + uri.getAuthority());
 }
 @Override
 public FileStatus[] listStatus(Path f) throws IOException {
   Path absolutePath = makeAbsolute(f);
   INode inode = store.retrieveINode(absolutePath);
   if (inode == null) {
     return new FileStatus[0];
   }
   if (inode.isFile()) {
     return new FileStatus[] {new OssFileStatus(f.makeQualified(this), inode)};
   }
   ArrayList<FileStatus> ret = new ArrayList<FileStatus>();
   for (Path p : store.listSubPaths(absolutePath)) {
     // Here, we need to convert "file/path" to "/file/path".
     // Otherwise, Path.makeQualified will throw `URISyntaxException`.
     Path modifiedPath = new Path("/" + p.toString());
     ret.add(getFileStatus(modifiedPath.makeQualified(this)));
   }
   return ret.toArray(new FileStatus[0]);
 }
 private INode checkFile(Path path) throws IOException {
   INode inode = store.retrieveINode(makeAbsolute(path));
   if (inode == null) {
     throw new IOException("No such file.");
   }
   if (inode.isDirectory()) {
     throw new IOException("Path " + path + " is a directory.");
   }
   return inode;
 }
  /** FileStatus for Oss file systems. */
  @Override
  public FileStatus getFileStatus(Path f) throws IOException {
    Path absolutePath = makeAbsolute(f);
    String key = JetOssFileSystemStore.pathToKey(absolutePath);

    if (key.length() == 0) { // root always exists
      return new OssFileStatus(f.makeQualified(this), INode.DIRECTORY_INODE);
    }

    INode inode = store.retrieveINode(makeAbsolute(f));
    if (inode == null) {
      throw new FileNotFoundException(f + ": No such file or directory.");
    }
    return new OssFileStatus(f.makeQualified(this), inode);
  }
 private boolean renameRecursive(Path src, Path dst) throws IOException {
   INode srcINode = store.retrieveINode(src);
   store.storeINode(dst, srcINode);
   store.deleteINode(src);
   if (srcINode.isDirectory()) {
     for (Path oldSrc : store.listDeepSubPaths(src)) {
       INode inode = store.retrieveINode(oldSrc);
       if (inode == null) {
         return false;
       }
       String oldSrcPath = oldSrc.toUri().getPath();
       String srcPath = src.toUri().getPath();
       String dstPath = dst.toUri().getPath();
       Path newDst = new Path(oldSrcPath.replaceFirst(srcPath, dstPath));
       store.storeINode(newDst, inode);
       store.deleteINode(oldSrc);
     }
   }
   return true;
 }
 /** @param permission Currently ignored. */
 @Override
 public FSDataOutputStream create(
     Path file,
     FsPermission permission,
     boolean overwrite,
     int bufferSize,
     short replication,
     long blockSize,
     Progressable progress)
     throws IOException {
   this.blocksForOneTime.clear();
   INode inode = store.retrieveINode(makeAbsolute(file));
   if (inode != null) {
     if (overwrite) {
       delete(file);
     } else {
       throw new IOException("File already exists: " + file);
     }
   } else {
     Path parent = file.getParent();
     if (parent != null) {
       if (!mkdirs(parent)) {
         throw new IOException("Mkdirs failed to create " + parent.toString());
       }
     }
   }
   return new FSDataOutputStream(
       new OssOutputStream(
           getConf(),
           store,
           makeAbsolute(file),
           blockSize,
           progress,
           bufferSize,
           blocksForOneTime),
       statistics);
 }
 void purge() throws IOException {
   store.purge();
 }
 void dump() throws IOException {
   store.dump();
 }