@Override
 public void createDirectory(SrvSession sess, TreeConnection tree, FileOpenParams params)
     throws IOException {
   try {
     FileFilterMode.setClient(ClientHelper.getClient(sess));
     try {
       diskInterface.createDirectory(sess, tree, params);
     } finally {
       FileFilterMode.clearClient();
     }
   } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
     throw new AccessDeniedException("Unable to create directory " + params.getPath(), ade);
   }
 }
  @Override
  public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params)
      throws IOException {
    ContentContext tctx = (ContentContext) tree.getContext();

    FileAccessToken token = null;

    if (tctx.hasStateCache()) {
      FileStateCache cache = tctx.getStateCache();
      FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true);
      token = cache.grantFileAccess(params, fstate, FileStatus.NotExist);
      if (logger.isDebugEnabled()) {
        logger.debug("create file created lock token:" + token);
      }
    }

    try {
      NetworkFile newFile = diskInterface.createFile(sess, tree, params);

      if (tctx.hasStateCache()) {
        FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true);
        fstate.setProcessId(params.getProcessId());
        fstate.setSharedAccess(params.getSharedAccess());

        // Indicate that the file is open
        fstate.setFileStatus(
            newFile.isDirectory() ? FileStatus.DirectoryExists : FileStatus.FileExists);
        fstate.setAllocationSize(params.getAllocationSize());

        if (newFile instanceof NodeRefNetworkFile) {
          NodeRefNetworkFile x = (NodeRefNetworkFile) newFile;
          x.setFileState(fstate);
        }

        if (newFile instanceof TempNetworkFile) {
          TempNetworkFile x = (TempNetworkFile) newFile;
          x.setFileState(fstate);
        }
      }

      if (newFile instanceof NodeRefNetworkFile) {
        NodeRefNetworkFile x = (NodeRefNetworkFile) newFile;
        x.setProcessId(params.getProcessId());
        x.setAccessToken(token);
      }

      if (newFile instanceof TempNetworkFile) {
        TempNetworkFile x = (TempNetworkFile) newFile;
        x.setAccessToken(token);
      }

      return newFile;

    } catch (IOException ie) {
      if (logger.isDebugEnabled()) {
        logger.debug("create file exception caught", ie);
      }
      if (tctx.hasStateCache() && token != null) {
        FileStateCache cache = tctx.getStateCache();
        FileState fstate = tctx.getStateCache().findFileState(params.getPath(), false);
        if (fstate != null && token != null) {
          if (logger.isDebugEnabled()) {
            logger.debug("create file release lock token:" + token);
          }
          cache.releaseFileAccess(fstate, token);
        }
      }
      throw ie;
    }
  }
  @Override
  public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams params)
      throws IOException {
    ContentContext tctx = (ContentContext) tree.getContext();
    String path = params.getPath();

    FileAccessToken token = null;

    if (tctx.hasStateCache()) {
      if (!params.isDirectory()) {
        FileStateCache cache = tctx.getStateCache();
        FileState fstate = tctx.getStateCache().findFileState(params.getPath(), true);
        token = cache.grantFileAccess(params, fstate, FileStatus.Unknown);
        if (logger.isDebugEnabled()) {
          logger.debug("open file created lock token:" + token);
        }
      }
    }

    try {
      NetworkFile openFile = diskInterface.openFile(sess, tree, params);

      if (openFile instanceof ContentNetworkFile) {
        ContentNetworkFile x = (ContentNetworkFile) openFile;
        x.setProcessId(params.getProcessId());
        x.setAccessToken(token);
        if (tctx.hasStateCache()) {
          FileState fstate = tctx.getStateCache().findFileState(path, true);
          x.setFileState(fstate);
          fstate.setProcessId(params.getProcessId());
          fstate.setSharedAccess(params.getSharedAccess());
          fstate.setFileStatus(FileStatus.FileExists);
        }
      }

      if (openFile instanceof TempNetworkFile) {
        TempNetworkFile x = (TempNetworkFile) openFile;
        x.setAccessToken(token);
        // x.setProcessId( params.getProcessId());
        if (tctx.hasStateCache()) {
          FileState fstate = tctx.getStateCache().findFileState(path, true);
          x.setFileState(fstate);
          fstate.setFileStatus(FileStatus.FileExists);
          fstate.setProcessId(params.getProcessId());
          fstate.setSharedAccess(params.getSharedAccess());
        }
      }

      if (openFile instanceof AlfrescoFolder) {
        AlfrescoFolder x = (AlfrescoFolder) openFile;
        // x.setProcessId( param.getProcessId());
        if (tctx.hasStateCache()) {
          FileState fstate = tctx.getStateCache().findFileState(path, true);
          x.setFileState(fstate);
          fstate.setFileStatus(FileStatus.DirectoryExists);
          fstate.setProcessId(params.getProcessId());
          fstate.setSharedAccess(params.getSharedAccess());
        }
      }

      return openFile;
    } catch (IOException ie) {
      if (logger.isDebugEnabled()) {
        logger.debug("open file exception caught", ie);
      }
      if (tctx.hasStateCache() && token != null) {
        FileStateCache cache = tctx.getStateCache();
        FileState fstate = tctx.getStateCache().findFileState(params.getPath(), false);
        if (fstate != null) {
          if (logger.isDebugEnabled()) {
            logger.debug("open file release lock token:" + token);
          }
          cache.releaseFileAccess(fstate, token);
        }
      }
      throw ie;
    }
  }
  @Override
  public NetworkFile openFile(SrvSession sess, TreeConnection tree, FileOpenParams param)
      throws IOException {
    String path = param.getPath();

    boolean truncate = param.isOverwrite();

    if (logger.isDebugEnabled()) {
      int sharedAccess = param.getSharedAccess();
      String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess);

      logger.debug(
          "openFile:"
              + path
              + ", isDirectory: "
              + param.isDirectory()
              + ", isStream: "
              + param.isStream()
              + ", readOnlyAccess: "
              + param.isReadOnlyAccess()
              + ", readWriteAccess: "
              + param.isReadWriteAccess()
              + ", writeOnlyAccess:"
              + param.isWriteOnlyAccess()
              + ", attributesOnlyAccess:"
              + param.isAttributesOnlyAccess()
              + ", sequentialAccessOnly:"
              + param.isSequentialAccessOnly()
              + ", writeThrough:"
              + param.isWriteThrough()
              + ", truncate:"
              + truncate
              + ", requestBatchOpLock:"
              + param.requestBatchOpLock()
              + ", requestExclusiveOpLock:"
              + param.requestExclusiveOpLock()
              + ", isDeleteOnClose:"
              + param.isDeleteOnClose()
              + ", allocationSize:"
              + param.getAllocationSize()
              + ", sharedAccess: "
              + strSharedAccess
              + ", openAction: "
              + param.getOpenAction()
              + param);
    }

    ContentContext tctx = (ContentContext) tree.getContext();
    NodeRef rootNode = tctx.getRootNode();

    DriverState driverState = getDriverState(sess);

    String[] paths = FileName.splitPath(path);
    String folder = paths[0];
    String file = paths[1];

    EvaluatorContext ctx = getEvaluatorContext(driverState, folder);

    OpenFileMode openMode = OpenFileMode.READ_ONLY;

    if (param.isAttributesOnlyAccess()) {
      openMode = OpenFileMode.ATTRIBUTES_ONLY;
    } else if (param.isReadWriteAccess()) {
      openMode = OpenFileMode.READ_WRITE;
    } else if (param.isWriteOnlyAccess()) {
      openMode = OpenFileMode.WRITE_ONLY;
    } else if (param.isReadOnlyAccess()) {
      openMode = OpenFileMode.READ_ONLY;
    } else if (param.isDeleteOnClose()) {
      if (logger.isDebugEnabled()) {
        logger.debug("open file has delete on close");
      }
      openMode = OpenFileMode.DELETE;
    }

    try {
      Operation o = new OpenFileOperation(file, openMode, truncate, rootNode, path);
      Command c = ruleEvaluator.evaluate(ctx, o);
      Object ret = commandExecutor.execute(sess, tree, c);

      if (ret != null && ret instanceof NetworkFile) {
        NetworkFile x = (NetworkFile) ret;

        if (logger.isDebugEnabled()) {
          logger.debug("returning open file: for path:" + path + ", ret:" + ret);
        }
        return x;
      } else {
        // Error - contact broken
        logger.error(
            "contract broken - NetworkFile not returned. " + ret == null
                ? "Return value is null"
                : ret);
        return null;
      }
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to open file " + param.getPath(), ade);
    }

    // return diskInterface.openFile(sess, tree, params);
  } // End of OpenFile
  @Override
  public NetworkFile createFile(SrvSession sess, TreeConnection tree, FileOpenParams params)
      throws IOException {
    try {
      int attr = params.getAttributes();
      if (logger.isDebugEnabled()) {
        int sharedAccess = params.getSharedAccess();
        String strSharedAccess = SharingMode.getSharingModeAsString(sharedAccess);

        logger.debug(
            "createFile:"
                + params.getPath()
                + ", isDirectory: "
                + params.isDirectory()
                + ", isStream: "
                + params.isStream()
                + ", readOnlyAccess: "
                + params.isReadOnlyAccess()
                + ", readWriteAccess: "
                + params.isReadWriteAccess()
                + ", writeOnlyAccess:"
                + params.isWriteOnlyAccess()
                + ", attributesOnlyAccess:"
                + params.isAttributesOnlyAccess()
                + ", sequentialAccessOnly:"
                + params.isSequentialAccessOnly()
                + ", requestBatchOpLock:"
                + params.requestBatchOpLock()
                + ", requestExclusiveOpLock:"
                + params.requestExclusiveOpLock()
                + ", isDeleteOnClose:"
                + params.isDeleteOnClose()
                + ", sharedAccess: "
                + strSharedAccess
                + ", allocationSize: "
                + params.getAllocationSize()
                + ", isHidden:"
                + FileAttribute.isHidden(attr)
                + ", isSystem:"
                + FileAttribute.isSystem(attr));
      }

      long creationDateTime = params.getCreationDateTime();
      if (creationDateTime != 0) {
        logger.debug("creationDateTime is set:" + new Date(creationDateTime));
      }

      ContentContext tctx = (ContentContext) tree.getContext();
      NodeRef rootNode = tctx.getRootNode();

      String[] paths = FileName.splitPath(params.getPath());
      String folder = paths[0];
      String file = paths[1];

      DriverState driverState = getDriverState(sess);
      EvaluatorContext ctx = getEvaluatorContext(driverState, folder);

      Operation o =
          new CreateFileOperation(
              file,
              rootNode,
              params.getPath(),
              params.getAllocationSize(),
              FileAttribute.isHidden(attr));
      Command c = ruleEvaluator.evaluate(ctx, o);

      Object ret = commandExecutor.execute(sess, tree, c);

      if (ret != null && ret instanceof NetworkFile) {
        return (NetworkFile) ret;
      } else {
        // Error - contact broken
        logger.error(
            "contract broken - NetworkFile not returned. " + ret == null
                ? "Return value is null"
                : ret);
        return null;
      }
    } catch (org.alfresco.repo.security.permissions.AccessDeniedException ade) {
      throw new AccessDeniedException("Unable to create file " + params.getPath(), ade);
    }
  }
  /**
   * Create a network file for the specified file
   *
   * @param params FileOpenParams
   * @param fid int
   * @param stid int
   * @param did int
   * @param create boolean
   * @param dir boolean
   * @exception IOException
   * @exception FileNotFoundException
   */
  public NetworkFile openFile(
      FileOpenParams params, int fid, int stid, int did, boolean create, boolean dir)
      throws IOException, FileNotFoundException {

    // Split the file name to get the name only

    String[] paths = FileName.splitPath(params.getPath());
    String name = paths[1];

    if (params.isStream()) name = name + params.getStreamName();

    // Find, or create, the file state for the file/directory

    FileState fstate = m_stateCache.findFileState(params.getFullPath(), true);
    fstate.setExpiryTime(System.currentTimeMillis() + m_stateCache.getFileStateExpireInterval());

    // Check if the file is a directory

    DBNetworkFile netFile = null;

    if (dir == false) {

      // Create the network file and associated file segment

      CachedNetworkFile cacheFile = createNetworkFile(fstate, params, name, fid, stid, did);
      netFile = cacheFile;

      // Check if the file is being opened for sequential access and the data has not yet been
      // loaded

      FileSegment fileSeg = cacheFile.getFileSegment();

      if (create == true || params.isOverwrite() == true) {

        // Indicate that the file data is available, this is a new file or the existing file is
        // being
        // overwritten so there is no data to load.

        fileSeg.setStatus(FileSegmentInfo.Available);
      } else if (params.isSequentialAccessOnly() && fileSeg.isDataLoading() == false) {

        synchronized (cacheFile.getFileState()) {

          // Create the temporary file

          cacheFile.openFile(create);
          cacheFile.closeFile();

          // Queue a file data load request

          if (fileSeg.isDataLoading() == false)
            queueFileRequest(
                new SingleFileRequest(
                    FileRequest.LOAD,
                    cacheFile.getFileId(),
                    cacheFile.getStreamId(),
                    fileSeg.getInfo(),
                    cacheFile.getFullName(),
                    fstate));
        }

        // DEBUG

        if (Debug.EnableInfo && hasDebug())
          Debug.println(
              "ObjIdLoader Queued file load, SEQUENTIAL access, file=" + cacheFile.getFullName());
      }
    } else {

      // Create a placeholder network file for the directory

      netFile = new DirectoryNetworkFile(name, fid, did, m_stateCache.getFileStateProxy(fstate));

      // Debug

      if (Debug.EnableInfo && hasDebug())
        Debug.println("ObjIdLoader.openFile() DIR name=" + name + ", state=" + fstate);
    }

    // Return the network file

    return netFile;
  }
  /**
   * Create a file segment to load/save the file data
   *
   * @param state FileState
   * @param params FileOpenParams
   * @param fname String
   * @param fid int
   * @param stid int
   * @param did int
   * @return CachedNetworkFile
   * @exception IOException
   */
  private final CachedNetworkFile createNetworkFile(
      FileState state, FileOpenParams params, String fname, int fid, int stid, int did)
      throws IOException {

    // The file state is used to synchronize the creation of the file segment as there may be other
    // sessions opening the file at the same time. We have to be careful that only one thread
    // creates the
    // file segment.

    FileSegment fileSeg = null;
    CachedNetworkFile netFile = null;

    synchronized (state) {

      // Check if the file segment has been attached to the file state

      FileSegmentInfo fileSegInfo = (FileSegmentInfo) state.findAttribute(DBFileSegmentInfo);
      if (fileSegInfo == null) {

        // Check if we need to create a new temporary sub-drectory

        if (m_tempCount++ >= m_tempMax) createNewTempDirectory();

        // Create a unique temporary file name

        StringBuffer tempName = new StringBuffer();
        tempName.append(getTempFilePrefix());
        tempName.append(fid);

        if (stid > 0) {
          tempName.append("_");
          tempName.append(stid);

          // DEBUG

          if (Debug.EnableInfo && hasDebug()) Debug.println("## Temp file for stream ##");
        }

        tempName.append(".tmp");

        // Create a new file segment

        fileSegInfo = new FileSegmentInfo();
        fileSeg =
            FileSegment.createSegment(
                fileSegInfo, tempName.toString(), m_curTempDir, params.isReadOnlyAccess() == false);

        // Add the segment to the file state cache

        state.addAttribute(DBFileSegmentInfo, fileSegInfo);

        // Check if the file is zero length, if so then set the file segment state to indicate it is
        // available

        DBFileInfo finfo = (DBFileInfo) state.findAttribute(FileState.FileInformation);
        if (finfo != null && finfo.getSize() == 0) fileSeg.setStatus(FileSegmentInfo.Available);
      } else {

        // Create the file segment to map to the existing temporary file

        fileSeg = new FileSegment(fileSegInfo, params.isReadOnlyAccess() == false);

        // Check if the temporary file exists, if not then create it

        File tempFile = new File(fileSeg.getTemporaryFile());
        if (tempFile.exists() == false) {

          // Create the temporary file

          tempFile.createNewFile();

          // Reset the file segment state to indicate a file load is required

          fileSeg.setStatus(FileSegmentInfo.Initial);
        }
      }

      // Create the new network file

      netFile =
          new CachedNetworkFile(
              fname, fid, stid, did, m_stateCache.getFileStateProxy(state), fileSeg, this);

      netFile.setGrantedAccess(
          params.isReadOnlyAccess() ? NetworkFile.READONLY : NetworkFile.READWRITE);
      netFile.setSequentialOnly(params.isSequentialAccessOnly());
      netFile.setAttributes(params.getAttributes());
      netFile.setFullName(params.getPath());

      if (stid != 0) netFile.setStreamName(params.getStreamName());
    }

    // Return the network file

    return netFile;
  }