FileEntity.java

  1. /*
  2.  * *************************************************************************************************************************************************************
  3.  *
  4.  * SteelBlue: DCI User Interfaces
  5.  * http://tidalwave.it/projects/steelblue
  6.  *
  7.  * Copyright (C) 2015 - 2025 by Tidalwave s.a.s. (http://tidalwave.it)
  8.  *
  9.  * *************************************************************************************************************************************************************
  10.  *
  11.  * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License.
  12.  * You may obtain a copy of the License at
  13.  *
  14.  *     http://www.apache.org/licenses/LICENSE-2.0
  15.  *
  16.  * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR
  17.  * CONDITIONS OF ANY KIND, either express or implied.  See the License for the specific language governing permissions and limitations under the License.
  18.  *
  19.  * *************************************************************************************************************************************************************
  20.  *
  21.  * git clone https://bitbucket.org/tidalwave/steelblue-src
  22.  * git clone https://github.com/tidalwave-it/steelblue-src
  23.  *
  24.  * *************************************************************************************************************************************************************
  25.  */
  26. package it.tidalwave.ui.example.model;

  27. import javax.annotation.Nonnegative;
  28. import javax.annotation.concurrent.Immutable;
  29. import jakarta.annotation.Nonnull;
  30. import java.time.ZoneId;
  31. import java.time.ZonedDateTime;
  32. import java.util.List;
  33. import java.util.Optional;
  34. import java.io.IOException;
  35. import java.nio.file.Files;
  36. import java.nio.file.Path;
  37. import java.nio.file.attribute.BasicFileAttributeView;
  38. import java.nio.file.attribute.BasicFileAttributes;
  39. import java.nio.file.attribute.FileTime;
  40. import it.tidalwave.ui.core.role.Displayable;
  41. import it.tidalwave.util.As;
  42. import it.tidalwave.util.Finder;
  43. import it.tidalwave.role.SimpleComposite;
  44. import lombok.EqualsAndHashCode;
  45. import lombok.ToString;
  46. import lombok.experimental.Delegate;
  47. import lombok.extern.slf4j.Slf4j;
  48. import static java.util.Collections.emptyList;
  49. import static java.util.Comparator.comparing;
  50. import static java.util.stream.Collectors.*;
  51. import static it.tidalwave.util.FunctionalCheckedExceptionWrappers.*;

  52. /***************************************************************************************************************************************************************
  53.  *
  54.  * A class that models a file with its attributes and children.
  55.  *
  56.  * @author  Fabrizio Giudici
  57.  *
  58.  **************************************************************************************************************************************************************/
  59. @Immutable @EqualsAndHashCode @ToString @Slf4j
  60. public class FileEntity implements As, Displayable
  61.   {
  62.     /** The path of the file.*/
  63.     @Nonnull
  64.     private final Path path;

  65.     /** Support object for implementing {@link As} functions.*/
  66.     @Delegate
  67.     private final As delegate;

  68.     /***********************************************************************************************************************************************************
  69.      * Creates a new instance related to the given path.
  70.      * @param   path    the path
  71.      **********************************************************************************************************************************************************/
  72.     // START SNIPPET: constructor
  73.     private FileEntity (@Nonnull final Path path)
  74.       {
  75.         this.path = path;
  76.         delegate = As.forObject(this, Files.isDirectory(path) ? List.of(SimpleComposite.of(Finder.ofSupplier(_s(() -> filesIn(path))))) : emptyList());
  77.       }
  78.     // END SNIPPET: constructor

  79.     /***********************************************************************************************************************************************************
  80.      * {@return a new instance} related to the given path.
  81.      * @param   path    the path
  82.      **********************************************************************************************************************************************************/
  83.     // START SNIPPET: constructor
  84.     @Nonnull
  85.     public static FileEntity of (@Nonnull final Path path)
  86.       {
  87.         return new FileEntity(path);
  88.       }
  89.     // END SNIPPET: constructor

  90.     /***********************************************************************************************************************************************************
  91.      * {@return the display name}. It's a static implementation of the {@link Displayable} role.
  92.      **********************************************************************************************************************************************************/
  93.     @Override @Nonnull
  94.     public String getDisplayName()
  95.       {
  96.         return Optional.ofNullable(path.getFileName()).map(Path::toString).orElse("/");
  97.       }

  98.     /***********************************************************************************************************************************************************
  99.      * {@return the creation date-time} of the file.
  100.      * @throws  IOException if the file does not exist or cannot be accessed
  101.      **********************************************************************************************************************************************************/
  102.     @Nonnull
  103.     public ZonedDateTime getCreationDateTime()
  104.             throws IOException
  105.       {
  106.         return toZoneDateTime(getBasicFileAttributes().creationTime());
  107.       }

  108.     /***********************************************************************************************************************************************************
  109.      * {@return the last access date-time} of the file.
  110.      * @throws  IOException if the file does not exist or cannot be accessed
  111.      **********************************************************************************************************************************************************/
  112.     @Nonnull
  113.     public ZonedDateTime getLastAccessDateTime()
  114.             throws IOException
  115.       {
  116.         return toZoneDateTime(getBasicFileAttributes().lastAccessTime());
  117.       }

  118.     /***********************************************************************************************************************************************************
  119.      * {@return the last modified date-time} of the file.
  120.      * @throws  IOException if the file does not exist or cannot be accessed
  121.      **********************************************************************************************************************************************************/
  122.     @Nonnull
  123.     public ZonedDateTime getLastModifiedDateTime()
  124.             throws IOException
  125.       {
  126.         return toZoneDateTime(getBasicFileAttributes().lastModifiedTime());
  127.       }

  128.     /***********************************************************************************************************************************************************
  129.      * {@return the size} of the file.
  130.      * @throws  IOException if the file does not exist or cannot be accessed
  131.      **********************************************************************************************************************************************************/
  132.     @Nonnegative
  133.     public long getSize()
  134.             throws IOException
  135.       {
  136.         return Files.size(path);
  137.       }

  138.     /***********************************************************************************************************************************************************
  139.      * {@return the basic attributes} of the file.
  140.      * @throws  IOException if the file does not exist or cannot be accessed
  141.      **********************************************************************************************************************************************************/
  142.     @Nonnull
  143.     private BasicFileAttributes getBasicFileAttributes()
  144.             throws IOException
  145.       {
  146.         return Files.getFileAttributeView(path, BasicFileAttributeView.class).readAttributes();
  147.       }

  148.     /***********************************************************************************************************************************************************
  149.      *
  150.      **********************************************************************************************************************************************************/
  151.     @Nonnull
  152.     private static List<FileEntity> filesIn (@Nonnull final Path path)
  153.             throws IOException
  154.       {
  155.         try (final var stream = Files.list(path))
  156.           {
  157.             return stream.sorted(comparing(Path::toString)).map(FileEntity::of).collect(toList());
  158.           }
  159.       }

  160.     /***********************************************************************************************************************************************************
  161.      *
  162.      **********************************************************************************************************************************************************/
  163.     @Nonnull
  164.     private static ZonedDateTime toZoneDateTime (@Nonnull final FileTime dateTime)
  165.       {
  166.         return ZonedDateTime.ofInstant(dateTime.toInstant(), ZoneId.systemDefault());
  167.       }
  168.   }