content: /*
   * The Alluxio Open Foundation licenses this work under the Apache License, version 2.0
   * (the "License"). You may not use this work except in compliance with the License, which is
   * available at www.apache.org/licenses/LICENSE-2.0
   *
   * This software is distributed on an "AS IS" basis, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND,
   * either express or implied, as more fully set forth in the License.
   *
   * See the NOTICE file distributed with this work for information regarding copyright ownership.
   */
  
  package alluxio.util.webui;
  
  import alluxio.AlluxioURI;
  import alluxio.client.file.URIStatus;
  import alluxio.conf.AlluxioConfiguration;
  import alluxio.conf.PropertyKey;
  import alluxio.master.file.meta.PersistenceState;
  import alluxio.security.authorization.Mode;
  import alluxio.util.CommonUtils;
  import alluxio.util.FormatUtils;
  import alluxio.wire.FileInfo;
  
  import com.google.common.base.Function;
  import com.google.common.base.Preconditions;
  import com.google.common.collect.Ordering;
  
  import java.util.ArrayList;
  import java.util.HashMap;
  import java.util.List;
  import java.util.Map;
  import java.util.stream.Collectors;
  import javax.annotation.concurrent.ThreadSafe;
  
  /**
   * Contains information about a file to be displayed in the UI.
   */
  @ThreadSafe
  public final class UIFileInfo {
    /**
     * Provides ordering of {@link alluxio.util.webui.UIFileInfo} based off a string comparison of the
     * absolute paths.
     */
    public static final Ordering<UIFileInfo> PATH_STRING_COMPARE = Ordering.natural()
        .onResultOf((Function<UIFileInfo, Comparable<String>>) input -> input.mAbsolutePath);
  
    /**
     * The type Local file info.
     */
    @ThreadSafe
    public static class LocalFileInfo {
      /**
       * The constant EMPTY_CREATION_TIME.
       */
      public static final long EMPTY_CREATION_TIME = 0;
  
      private final String mName;
      private final String mAbsolutePath;
      private final long mSize;
      private final long mCreationTimeMs;
      private final long mLastModificationTimeMs;
      private final boolean mIsDirectory;
  
      /**
       * Creates a new instance of {@link alluxio.util.webui.UIFileInfo.LocalFileInfo}.
       *
       * @param name name
       * @param absolutePath absolute path
       * @param size size
       * @param creationTimeMs creation time in milliseconds
       * @param lastModificationTimeMs last modification time in milliseconds
       * @param isDirectory whether the object represents a directory
       */
      public LocalFileInfo(String name, String absolutePath, long size, long creationTimeMs,
          long lastModificationTimeMs, boolean isDirectory) {
        mName = Preconditions.checkNotNull(name, "name");
        mAbsolutePath = Preconditions.checkNotNull(absolutePath, "absolutePath");
        mSize = size;
        mCreationTimeMs = creationTimeMs;
        mLastModificationTimeMs = lastModificationTimeMs;
        mIsDirectory = isDirectory;
      }
    }
  
    private final long mId;
    private final String mName;
    private final String mAbsolutePath;
    private final long mBlockSizeBytes;
    private final long mSize;
    private final long mCreationTimeMs;
    private final long mLastModificationTimeMs;
    private final boolean mInAlluxio;
    private final int mInAlluxioPercentage;
    private final boolean mIsDirectory;
    private final boolean mPinned;
    private final String mOwner;
    private final String mGroup;
    private final String mMode;
    private final String mPersistenceState;
    private final List<String> mFileLocations;
    private final AlluxioConfiguration mAlluxioConfiguration;
    private final List<String> mOrderedTierAliases;
  
    private final Map<String, List<UIFileBlockInfo>> mBlocksOnTier = new HashMap<>();
    private final Map<String, Long> mSizeOnTier = new HashMap<>();
    private final List<Long> mBlockIds = new ArrayList<>();
  
    /**
     * Creates a new instance of {@link alluxio.util.webui.UIFileInfo}.
     *
     * @param status underlying {@link URIStatus}
     * @param alluxioConfiguration the alluxio configuration
     * @param orderedTierAliases the ordered tier aliases
     */
    public UIFileInfo(URIStatus status, AlluxioConfiguration alluxioConfiguration,
        List<String> orderedTierAliases) {
      // detect the extended acls
      boolean hasExtended = status.getAcl().hasExtended() || !status.getDefaultAcl().isEmpty();
  
      mId = status.getFileId();
      mName = status.getName();
      mAbsolutePath = status.getPath();
      mBlockSizeBytes = status.getBlockSizeBytes();
      mSize = status.getLength();
      mCreationTimeMs = status.getCreationTimeMs();
      mLastModificationTimeMs = status.getLastModificationTimeMs();
      mInAlluxio = (100 == status.getInAlluxioPercentage());
      mInAlluxioPercentage = status.getInAlluxioPercentage();
      mIsDirectory = status.isFolder();
      mPinned = status.isPinned();
      mOwner = status.getOwner();
      mGroup = status.getGroup();
      mMode = FormatUtils.formatMode((short) status.getMode(), status.isFolder(), hasExtended);
      mPersistenceState = status.getPersistenceState();
      mFileLocations = new ArrayList<>();
      mAlluxioConfiguration = alluxioConfiguration;
      mOrderedTierAliases = orderedTierAliases;
    }
  
    /**
     * Creates a new instance of {@link alluxio.util.webui.UIFileInfo}.
     *
     * @param info underlying {@link FileInfo}
     * @param alluxioConfiguration the alluxio configuration
     * @param orderedTierAliases the ordered tier aliases
     */
    public UIFileInfo(FileInfo info, AlluxioConfiguration alluxioConfiguration,
        List<String> orderedTierAliases) {
      this(new URIStatus(info), alluxioConfiguration, orderedTierAliases);
    }
  
    /**
     * Creates a new instance of {@link alluxio.util.webui.UIFileInfo}.
     *
     * @param fileInfo underlying {@link alluxio.util.webui.UIFileInfo.LocalFileInfo}
     * @param alluxioConfiguration the alluxio configuration
     * @param orderedTierAliases the ordered tier aliases
     */
    public UIFileInfo(UIFileInfo.LocalFileInfo fileInfo, AlluxioConfiguration alluxioConfiguration,
        List<String> orderedTierAliases) {
      mId = -1;
      mName = fileInfo.mName;
      mAbsolutePath = fileInfo.mAbsolutePath;
      mBlockSizeBytes = 0;
      mSize = fileInfo.mSize;
      mCreationTimeMs = fileInfo.mCreationTimeMs;
      mLastModificationTimeMs = fileInfo.mLastModificationTimeMs;
      mInAlluxio = false;
      mInAlluxioPercentage = 0;
      mIsDirectory = fileInfo.mIsDirectory;
      mPinned = false;
      mOwner = "";
      mGroup = "";
      mMode = FormatUtils.formatMode(Mode.createNoAccess().toShort(), true, false);
      mPersistenceState = PersistenceState.NOT_PERSISTED.name();
      mFileLocations = new ArrayList<>();
      mAlluxioConfiguration = alluxioConfiguration;
      mOrderedTierAliases = orderedTierAliases;
    }
  
    /**
     * Adds a block to the file information.
     *
     * @param tierAlias the tier alias
     * @param blockId the block id
     * @param blockSize the block size
     * @param blockLastAccessTimeMs the last access time (in milliseconds)
     */
    public void addBlock(String tierAlias, long blockId, long blockSize, long blockLastAccessTimeMs) {
      UIFileBlockInfo block =
          new UIFileBlockInfo(blockId, blockSize, blockLastAccessTimeMs, tierAlias,
              mAlluxioConfiguration);
      List<UIFileBlockInfo> blocksOnTier = mBlocksOnTier.computeIfAbsent(tierAlias,
          k -> new ArrayList<>());
      blocksOnTier.add(block);
  
      Long sizeOnTier = mSizeOnTier.get(tierAlias);
      mSizeOnTier.put(tierAlias, (sizeOnTier == null ? 0L : sizeOnTier) + blockSize);
      mBlockIds.add(blockId);
    }
  
    /**
     * Gets absolute path.
     *
     * @return the absolute path
     */
    public String getAbsolutePath() {
      return mAbsolutePath;
    }
  
    /**
     * Gets block size bytes.
     *
     * @return the block size (in bytes)
     */
    public String getBlockSizeBytes() {
      if (mIsDirectory) {
        return "";
      } else {
        return FormatUtils.getSizeFromBytes(mBlockSizeBytes);
      }
    }
  
    /**
     * Gets blocks on tier.
     *
     * @return a mapping from tiers to file blocks
     */
    public Map<String, List<UIFileBlockInfo>> getBlocksOnTier() {
      return mBlocksOnTier;
    }
  
    /**
     * Gets creation time.
     *
     * @return the creation time (in milliseconds)
     */
    public String getCreationTime() {
      if (mCreationTimeMs == UIFileInfo.LocalFileInfo.EMPTY_CREATION_TIME) {
        return "";
      }
      return CommonUtils.convertMsToDate(mCreationTimeMs,
          mAlluxioConfiguration.getString(PropertyKey.USER_DATE_FORMAT_PATTERN));
    }
  
    /**
     * Gets modification time.
     *
     * @return the modification time (in milliseconds)
     */
    public String getModificationTime() {
      return CommonUtils.convertMsToDate(mLastModificationTimeMs,
          mAlluxioConfiguration.getString(PropertyKey.USER_DATE_FORMAT_PATTERN));
    }
  
    /**
     * Gets file locations.
     *
     * @return the file locations
     */
    public List<String> getFileLocations() {
      return mFileLocations;
    }
  
    /**
     * Gets id.
     *
     * @return the file id
     */
    public long getId() {
      return mId;
    }
  
    /**
     * Gets in alluxio.
     *
     * @return whether the file is present in memory
     */
    public boolean getInAlluxio() {
      return mInAlluxio;
    }
  
    /**
     * Gets in alluxio percentage.
     *
     * @return the percentage of the file present in memory
     */
    public int getInAlluxioPercentage() {
      return mInAlluxioPercentage;
    }
  
    /**
     * Gets is directory.
     *
     * @return whether the object represents a directory
     */
    public boolean getIsDirectory() {
      return mIsDirectory;
    }
  
    /**
     * Is pinned boolean.
     *
     * @return whether the file is pinned
     */
    public boolean isPinned() {
      return mPinned;
    }
  
    /**
     * Gets persistence state.
     *
     * @return the {@link PersistenceState} of the file
     */
    public String getPersistenceState() {
      return mPersistenceState;
    }
  
    /**
     * Gets on-tier percentages.
     *
     * @return the on-tier percentages
     */
    public Map<String, Integer> getOnTierPercentages() {
      return mOrderedTierAliases.stream().collect(Collectors.toMap(tier -> tier, tier -> {
        Long sizeOnTier = mSizeOnTier.getOrDefault(tier, 0L);
        return mSize > 0 ? (int) (100 * sizeOnTier / mSize) : 0;
      }));
    }
  
    /**
     * Gets name.
     *
     * @return the file name
     */
    public String getName() {
      if (AlluxioURI.SEPARATOR.equals(mAbsolutePath)) {
        return "root";
      } else {
        return mName;
      }
    }
  
    /**
     * Gets size.
     *
     * @return the file size
     */
    public String getSize() {
      if (mIsDirectory) {
        return "";
      } else {
        return FormatUtils.getSizeFromBytes(mSize);
      }
    }
  
    /**
     * Sets file locations.
     *
     * @param fileLocations the file locations to use
     */
    public void setFileLocations(List<String> fileLocations) {
      mFileLocations.clear();
      mFileLocations.addAll(fileLocations);
    }
  
    /**
     * Gets owner.
     *
     * @return the owner of the file
     */
    public String getOwner() {
      return mOwner;
    }
  
    /**
     * Gets group.
     *
     * @return the group of the file
     */
    public String getGroup() {
      return mGroup;
    }
  
    /**
     * Gets mode.
     *
     * @return the mode of the file
     */
    public String getMode() {
      return mMode;
    }
  
    /**
     * Gets BlockId List.
     *
     * @return the BlockId List in worker node
     */
    public List<Long> getBlockIds() {
      return mBlockIds;
    }
  }
  