VirtualMediaFolder.java

  1. /*
  2.  * *********************************************************************************************************************
  3.  *
  4.  * blueMarine II: Semantic Media Centre
  5.  * http://tidalwave.it/projects/bluemarine2
  6.  *
  7.  * Copyright (C) 2015 - 2021 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
  12.  * the License. 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
  17.  * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.  See the License for the
  18.  * specific language governing permissions and limitations under the License.
  19.  *
  20.  * *********************************************************************************************************************
  21.  *
  22.  * git clone https://bitbucket.org/tidalwave/bluemarine2-src
  23.  * git clone https://github.com/tidalwave-it/bluemarine2-src
  24.  *
  25.  * *********************************************************************************************************************
  26.  */
  27. package it.tidalwave.bluemarine2.model;

  28. import javax.annotation.Nonnull;
  29. import java.util.Collection;
  30. import java.util.Optional;
  31. import java.util.function.Function;
  32. import java.nio.file.Path;
  33. import it.tidalwave.util.Id;
  34. import it.tidalwave.role.Identifiable;
  35. import it.tidalwave.role.ui.Displayable;
  36. import it.tidalwave.bluemarine2.model.spi.EntityWithRoles;
  37. import it.tidalwave.bluemarine2.model.spi.PathAwareEntity;
  38. import it.tidalwave.bluemarine2.model.spi.PathAwareFinder;
  39. import lombok.Getter;
  40. import lombok.ToString;
  41. import static it.tidalwave.util.Parameters.r;

  42. /***********************************************************************************************************************
  43.  *
  44.  * Represents a folder which doesn't have a physical counterpart in the repository. It can be used to created in-memory
  45.  * aggregations of media items.
  46.  *
  47.  * @stereotype  Datum
  48.  *
  49.  * @author  Fabrizio Giudici
  50.  *
  51.  **********************************************************************************************************************/
  52. @ToString(exclude = "finderFactory")
  53. public class VirtualMediaFolder extends EntityWithRoles implements MediaFolder
  54.   {
  55.     // These two interfaces are needed to avoid clashes with constructor overloading
  56.     public static interface EntityCollectionFactory extends Function<MediaFolder, Collection<? extends PathAwareEntity>>
  57.       {
  58.       }

  59.     public static interface EntityFinderFactory extends Function<MediaFolder, PathAwareFinder>
  60.       {
  61.       }

  62.     @Getter @Nonnull
  63.     private final Path path;

  64.     @Nonnull
  65.     private final Optional<? extends MediaFolder> optionalParent;

  66.     @Nonnull
  67.     private final EntityFinderFactory finderFactory;

  68.     public VirtualMediaFolder (@Nonnull final MediaFolder parent,
  69.                                @Nonnull final Path pathSegment,
  70.                                @Nonnull final String displayName,
  71.                                @Nonnull final EntityCollectionFactory childrenFactory)
  72.       {
  73.         this(Optional.of(parent), pathSegment, displayName, Optional.of(childrenFactory), Optional.empty());
  74.       }

  75.     public VirtualMediaFolder (@Nonnull final Optional<? extends MediaFolder> optionalParent,
  76.                                @Nonnull final Path pathSegment,
  77.                                @Nonnull final String displayName,
  78.                                @Nonnull final EntityCollectionFactory childrenFactory)
  79.       {
  80.         this(optionalParent, pathSegment, displayName, Optional.of(childrenFactory), Optional.empty());
  81.       }

  82.     public VirtualMediaFolder (@Nonnull final MediaFolder parent,
  83.                                @Nonnull final Path pathSegment,
  84.                                @Nonnull final String displayName,
  85.                                @Nonnull final EntityFinderFactory finderFactory)
  86.       {
  87.         this(Optional.of(parent), pathSegment, displayName, Optional.empty(), Optional.of(finderFactory));
  88.       }

  89.     public VirtualMediaFolder (@Nonnull final Optional<? extends MediaFolder> optionalParent,
  90.                                @Nonnull final Path pathSegment,
  91.                                @Nonnull final String displayName,
  92.                                @Nonnull final EntityFinderFactory finderFactory)
  93.       {
  94.         this(optionalParent, pathSegment, displayName, Optional.empty(), Optional.of(finderFactory));
  95.       }

  96.     private VirtualMediaFolder (@Nonnull final Optional<? extends MediaFolder> optionalParent,
  97.                                 @Nonnull final Path pathSegment,
  98.                                 @Nonnull final String displayName,
  99.                                 @Nonnull final Optional<EntityCollectionFactory> childrenSupplier,
  100.                                 @Nonnull final Optional<EntityFinderFactory> finderFactory)
  101.       {
  102.         // FIXME: review if first should be prioritised
  103.         super(r((Identifiable)() -> Id.of(absolutePath(optionalParent, pathSegment).toString()),
  104.               Displayable.of(displayName)));
  105.         this.path = absolutePath(optionalParent, pathSegment);
  106.         this.optionalParent = optionalParent;
  107.         this.finderFactory = finderFactory.orElse(mediaFolder -> mediaFolder.finderOf(childrenSupplier.get()));
  108.       }

  109.     @Override @Nonnull
  110.     public Optional<PathAwareEntity> getParent()
  111.       {
  112.         return (Optional<PathAwareEntity>)(Object)optionalParent;
  113.       }

  114.     @Override @Nonnull
  115.     public PathAwareFinder findChildren()
  116.       {
  117.         return finderFactory.apply(this);
  118.       }

  119.     @Override @Nonnull
  120.     public String toDumpString()
  121.       {
  122.         return String.format("Folder(path=%s)", path);
  123.       }

  124.     @Nonnull
  125.     private static Path absolutePath (@Nonnull final Optional<? extends MediaFolder> optionalParent,
  126.                                       @Nonnull final Path pathSegment)
  127.       {
  128.         return optionalParent.map(parent -> parent.getPath().resolve(pathSegment)).orElse(pathSegment);
  129.       }
  130.   }