/**
  * Creates and/or returns an internal folder called {@code .trash} located just below the user's
  * home folder.
  */
 private Node getOrCreateTrashInternalFolderNode(
     final Session session, final PentahoJcrConstants pentahoJcrConstants)
     throws RepositoryException {
   IPentahoSession pentahoSession = PentahoSessionHolder.getSession();
   String tenantId = (String) pentahoSession.getAttribute(IPentahoSession.TENANT_ID_KEY);
   Node userHomeFolderNode =
       (Node)
           session.getItem(
               ServerRepositoryPaths.getUserHomeFolderPath(
                   new Tenant(tenantId, true),
                   JcrStringHelper.fileNameEncode(PentahoSessionHolder.getSession().getName())));
   if (userHomeFolderNode.hasNode(FOLDER_NAME_TRASH)) {
     return userHomeFolderNode.getNode(FOLDER_NAME_TRASH);
   } else {
     return userHomeFolderNode.addNode(
         FOLDER_NAME_TRASH, pentahoJcrConstants.getPHO_NT_INTERNALFOLDER());
   }
 }
  /** {@inheritDoc} */
  public void permanentlyDeleteFile(
      final Session session,
      final PentahoJcrConstants pentahoJcrConstants,
      final Serializable fileId)
      throws RepositoryException {
    Assert.notNull(fileId);
    Node fileNode = session.getNodeByIdentifier(fileId.toString());
    // guard against using a file retrieved from a more lenient session inside a more strict session
    Assert.notNull(fileNode);

    // see if anything is referencing this node; if yes, then we cannot delete it as a
    // ReferentialIntegrityException
    // will result
    Set<RepositoryFile> referrers = new HashSet<RepositoryFile>();
    PropertyIterator refIter = fileNode.getReferences();
    if (refIter.hasNext()) {
      while (refIter.hasNext()) {
        // for each referrer property, march up the tree until we find the file node to which the
        // property belongs
        RepositoryFile referrer =
            getReferrerFile(session, pentahoJcrConstants, refIter.nextProperty());
        if (referrer != null) {
          referrers.add(referrer);
        }
      }
      if (!referrers.isEmpty()) {
        RepositoryFile referee =
            JcrRepositoryFileUtils.nodeToFile(
                session, pentahoJcrConstants, pathConversionHelper, lockHelper, fileNode);
        throw new RepositoryFileDaoReferentialIntegrityException(referee, referrers);
      }
    }

    // technically, the node can be deleted while it is locked; however, we want to avoid an
    // orphaned lock token;
    // delete
    // it first
    if (fileNode.isLocked()) {
      Lock lock = session.getWorkspace().getLockManager().getLock(fileNode.getPath());
      // don't need lock token anymore
      lockHelper.removeLockToken(session, pentahoJcrConstants, lock);
    }

    // if this file was non-permanently deleted, delete its containing folder too
    IPentahoSession pentahoSession = PentahoSessionHolder.getSession();
    String tenantId = (String) pentahoSession.getAttribute(IPentahoSession.TENANT_ID_KEY);
    String trashFolder =
        ServerRepositoryPaths.getUserHomeFolderPath(
                new Tenant(tenantId, true), PentahoSessionHolder.getSession().getName())
            + RepositoryFile.SEPARATOR
            + FOLDER_NAME_TRASH;
    Node parent = fileNode.getParent();

    purgeHistory(fileNode, session, pentahoJcrConstants);

    if (fileNode.getPath().startsWith(trashFolder)) {
      // Remove the file and then the wrapper foler
      fileNode.remove();
      parent.remove();
    } else {
      fileNode.remove();
    }
  }
  private RepositoryFile createUserHomeFolder(ITenant theTenant, String username, Session session)
      throws RepositoryException {
    Builder aclsForUserHomeFolder = null;
    Builder aclsForTenantHomeFolder = null;

    if (theTenant == null) {
      theTenant = JcrTenantUtils.getTenant(username, true);
      username = JcrTenantUtils.getPrincipalName(username, true);
    }
    if (theTenant == null || theTenant.getId() == null) {
      theTenant = JcrTenantUtils.getCurrentTenant();
    }
    if (theTenant == null || theTenant.getId() == null) {
      theTenant = JcrTenantUtils.getDefaultTenant();
    }
    RepositoryFile userHomeFolder = null;
    String userId = tenantedUserNameUtils.getPrincipleId(theTenant, username);
    final RepositoryFileSid userSid = new RepositoryFileSid(userId);
    RepositoryFile tenantHomeFolder = null;
    RepositoryFile tenantRootFolder = null;
    RepositoryFileSid ownerSid = null;
    // Get the Tenant Root folder. If the Tenant Root folder does not exist then exit.
    tenantRootFolder =
        JcrRepositoryFileUtils.getFileByAbsolutePath(
            session,
            ServerRepositoryPaths.getTenantRootFolderPath(theTenant),
            pathConversionHelper,
            lockHelper,
            false,
            null);
    if (tenantRootFolder != null) {
      // Try to see if Tenant Home folder exist
      tenantHomeFolder =
          JcrRepositoryFileUtils.getFileByAbsolutePath(
              session,
              ServerRepositoryPaths.getTenantHomeFolderPath(theTenant),
              pathConversionHelper,
              lockHelper,
              false,
              null);

      if (tenantHomeFolder == null) {
        String ownerId = tenantedUserNameUtils.getPrincipleId(theTenant, username);
        ownerSid = new RepositoryFileSid(ownerId, Type.USER);

        String tenantAuthenticatedRoleId =
            tenantedRoleNameUtils.getPrincipleId(theTenant, authenticatedRoleName);
        RepositoryFileSid tenantAuthenticatedRoleSid =
            new RepositoryFileSid(tenantAuthenticatedRoleId, Type.ROLE);

        aclsForTenantHomeFolder =
            new RepositoryFileAcl.Builder(userSid)
                .ace(tenantAuthenticatedRoleSid, EnumSet.of(RepositoryFilePermission.READ));

        aclsForUserHomeFolder =
            new RepositoryFileAcl.Builder(userSid)
                .ace(ownerSid, EnumSet.of(RepositoryFilePermission.ALL));
        tenantHomeFolder =
            internalCreateFolder(
                session,
                tenantRootFolder.getId(),
                new RepositoryFile.Builder(ServerRepositoryPaths.getTenantHomeFolderName())
                    .folder(true)
                    .title(
                        Messages.getInstance()
                            .getString("AbstractJcrBackedUserRoleDao.usersFolderDisplayName"))
                    .build(),
                aclsForTenantHomeFolder.build(),
                "tenant home folder"); //$NON-NLS-1$
      } else {
        String ownerId = tenantedUserNameUtils.getPrincipleId(theTenant, username);
        ownerSid = new RepositoryFileSid(ownerId, Type.USER);
        aclsForUserHomeFolder =
            new RepositoryFileAcl.Builder(userSid)
                .ace(ownerSid, EnumSet.of(RepositoryFilePermission.ALL));
      }

      // now check if user's home folder exist
      userHomeFolder =
          JcrRepositoryFileUtils.getFileByAbsolutePath(
              session,
              ServerRepositoryPaths.getUserHomeFolderPath(theTenant, username),
              pathConversionHelper,
              lockHelper,
              false,
              null);
      if (userHomeFolder == null) {
        userHomeFolder =
            internalCreateFolder(
                session,
                tenantHomeFolder.getId(),
                new RepositoryFile.Builder(username).folder(true).build(),
                aclsForUserHomeFolder.build(),
                "user home folder"); //$NON-NLS-1$
      }
    }
    return userHomeFolder;
  }