public boolean delete(File file) {
    removeLocalInputFile(file);

    String owner = this.buildNewOwnerId("delete");
    AbstractProxy proxy = this.getAvailableProxy(owner);
    boolean res = false;
    try {
      FileCacheableInformations infos = this.getInformations(file);
      if (infos.isExists()) {
        if (infos.isDirectory()) {
          res = proxy.deleteDir(this.translateToRemote(file));
        } else {
          res = proxy.deleteFile(this.translateToRemote(file));
        }
      } else {
        res = true;
      }
    } catch (RemoteConnectionException e) {
      Logger.defaultLogger()
          .error("Error caught while deleting " + FileSystemManager.getDisplayPath(file), e);
      throw new UnexpectedConnectionException(e);
    } finally {
      this.releaseProxy(proxy, owner);
    }

    return res;
  }
  public File[] listFiles(File file) {
    String owner = this.buildNewOwnerId("listFiles");
    AbstractProxy proxy = (AbstractProxy) this.getAvailableProxy(owner);
    FictiveFile[] files = null;
    File[] returned = null;
    try {
      files = proxy.listFiles(this.translateToRemote(file));
      returned = new File[files.length];
      for (int i = 0; i < files.length; i++) {
        returned[i] =
            new FictiveFile(
                translateToLocal(files[i].getRemotePath()),
                files[i].getRemotePath(),
                files[i].length(),
                files[i].isDirectory(),
                files[i].exists(),
                files[i].lastModified());
      }
    } catch (RemoteConnectionException e) {
      Logger.defaultLogger().error(e);
      throw new UnexpectedConnectionException(e);
    } finally {
      this.releaseProxy(proxy, owner);
    }

    return returned;
  }
 protected void initFictiveLocalFile(FictiveFile file) {
   String owner = this.buildNewOwnerId("initFictiveLocalFile");
   AbstractProxy proxy = this.getAvailableProxy(owner);
   try {
     proxy.initFictiveLocalFile(file);
   } finally {
     this.releaseProxy(proxy, owner);
   }
 }
 public boolean createNewFile(File file) throws IOException {
   String owner = this.buildNewOwnerId("createNewFile");
   AbstractProxy proxy = this.getAvailableProxy(owner);
   boolean res = false;
   try {
     res = proxy.createNewFile(this.translateToRemote(file));
   } finally {
     this.releaseProxy(proxy, owner);
   }
   return res;
 }
 public synchronized void flush() throws IOException {
   // Flush all proxies
   Iterator iter = this.alternateProxies.iterator();
   while (iter.hasNext()) {
     AbstractProxy proxy = (AbstractProxy) iter.next();
     proxy.flush();
   }
   this.proxy.flush();
   Logger.defaultLogger().info("Flush completed.");
   Logger.defaultLogger()
       .info("" + this.alternateProxies.size() + " alternate proxies are currently active.");
 }
 protected void disconnect() {
   Logger.defaultLogger().info("Disconnecting all proxies ...");
   Logger.defaultLogger().fine("Disconnecting main proxy ...");
   this.proxy.disconnect();
   Iterator iter = this.alternateProxies.iterator();
   int i = 0;
   while (iter.hasNext()) {
     Logger.defaultLogger().fine("Disconnecting proxy #" + ++i + " ...");
     AbstractProxy px = (AbstractProxy) iter.next();
     px.disconnect();
   }
 }
  public boolean mkdir(File file) {
    String owner = this.buildNewOwnerId("mkdir");
    AbstractProxy proxy = this.getAvailableProxy(owner);
    boolean res = false;
    try {
      res = proxy.mkdir(this.translateToRemote(file));
    } catch (RemoteConnectionException e) {
      Logger.defaultLogger()
          .error("Error creating directory : " + FileSystemManager.getDisplayPath(file));
      throw new UnexpectedConnectionException(e);
    } finally {
      this.releaseProxy(proxy, owner);
    }

    return res;
  }
  public boolean renameTo(File source, File dest) {
    removeLocalInputFile(source);
    removeLocalInputFile(dest);

    String owner = this.buildNewOwnerId("renameTo");
    AbstractProxy proxy = (AbstractProxy) this.getAvailableProxy(owner);
    boolean res = false;
    try {
      res = proxy.renameTo(this.translateToRemote(source), this.translateToRemote(dest));
    } catch (RemoteConnectionException e) {
      throw new UnexpectedConnectionException(e);
    } finally {
      this.releaseProxy(proxy, owner);
    }

    return res;
  }
  public InputStream getFileInputStream(File file) throws IOException {
    String owner = this.buildNewOwnerId("getFileInputStream");
    AbstractProxy proxy = this.getAvailableProxy(owner);

    try {
      InputStream raw = proxy.getFileInputStream(this.translateToRemote(file));

      if (USE_BUFFER) {
        return new BufferedInputStream(raw, BUFFER_SIZE);
      } else {
        return raw;
      }
    } catch (IOException e) {
      releaseProxy(proxy, owner);
      throw e;
    } catch (RuntimeException e) {
      releaseProxy(proxy, owner);
      throw e;
    }
    // Pas de "releaseLock" systematique ici car c'est le stream qui s'en charge a la fermeture
  }
  protected synchronized AbstractProxy getAvailableProxy(String owner) {
    if (this.proxy.acquireLock(owner)) {
      return proxy;
    } else {
      Iterator iter = this.alternateProxies.iterator();
      while (iter.hasNext()) {
        AbstractProxy alternateProxy = (AbstractProxy) iter.next();
        if (alternateProxy.acquireLock(owner)) {
          return alternateProxy;
        }
      }

      if (this.alternateProxies.size() == maxProxies) {
        Logger.defaultLogger()
            .error(
                "Maximum number of proxies ("
                    + maxProxies
                    + ") reached - Unable to create another proxy",
                "getAvailableProxy");
        Logger.defaultLogger().info("Main Proxy : " + this.proxy.getOwnerId());
        Iterator piter = this.alternateProxies.iterator();
        while (piter.hasNext()) {
          AbstractProxy px = (AbstractProxy) piter.next();
          Logger.defaultLogger().info("Alternate Proxy : " + px.getOwnerId());
        }
        return null;
      } else {
        Logger.defaultLogger()
            .info(
                "Creating a new proxy on "
                    + this.proxy.toString()
                    + " : "
                    + +(this.alternateProxies.size() + 1)
                    + " th.");
        AbstractProxy newProxy = this.proxy.cloneProxy();
        newProxy.acquireLock(owner);
        this.alternateProxies.add(newProxy);
        return newProxy;
      }
    }
  }
 public void clearCachedData(File file) throws IOException {
   proxy.removeCachedFileInfos(this.translateToRemote(file));
 }
 protected void releaseProxy(AbstractProxy proxy, String owner) {
   if (proxy != null) {
     proxy.releaseLock(owner);
   }
 }