001package arez.component.internal;
002
003import arez.Arez;
004import grim.annotations.OmitType;
005import java.util.Collection;
006import java.util.Collections;
007import java.util.List;
008import java.util.Map;
009import java.util.Set;
010import java.util.stream.Collectors;
011import java.util.stream.Stream;
012import javax.annotation.Nonnull;
013
014/**
015 * Utility methods used when returning results from repositories.
016 */
017@OmitType( unless = "arez.collections_properties_unmodifiable" )
018public final class CollectionsUtil
019{
020  private CollectionsUtil()
021  {
022  }
023
024  /**
025   * Wrap specified parameter with unmodifiable variant if and only if {@link Arez#areCollectionsPropertiesUnmodifiable()}
026   * returns true, otherwise return the supplied list. This method is invoked by the generated code when it detects
027   * list properties and should be used by repository extensions when returning collection results.
028   *
029   * @param <T>        the type of elements in collection.
030   * @param collection the input collection.
031   * @return the output collection.
032   */
033  @Nonnull
034  public static <T> Collection<T> wrap( @Nonnull final Collection<T> collection )
035  {
036    return Arez.areCollectionsPropertiesUnmodifiable() ? Collections.unmodifiableCollection( collection ) : collection;
037  }
038
039  /**
040   * Wrap specified parameter with unmodifiable set if and only if {@link Arez#areCollectionsPropertiesUnmodifiable()}
041   * returns true, otherwise return the supplied set. This method is invoked by the generated code when it detects
042   * set properties and should be used by repository extensions when returning set results.
043   *
044   * @param <T> the type of elements in set.
045   * @param set the input set.
046   * @return the output set.
047   */
048  @Nonnull
049  public static <T> Set<T> wrap( @Nonnull final Set<T> set )
050  {
051    return Arez.areCollectionsPropertiesUnmodifiable() ? Collections.unmodifiableSet( set ) : set;
052  }
053
054  /**
055   * Wrap specified parameter with unmodifiable map if and only if {@link Arez#areCollectionsPropertiesUnmodifiable()}
056   * returns true, otherwise return the supplied map. This method is invoked by the generated code when it detects
057   * map properties and should be used by repository extensions when returning map results.
058   *
059   * @param <K> the type of key elements in map.
060   * @param <V> the type of value elements in map.
061   * @param map the input map.
062   * @return the output map.
063   */
064  @Nonnull
065  public static <K, V> Map<K, V> wrap( @Nonnull final Map<K, V> map )
066  {
067    return Arez.areCollectionsPropertiesUnmodifiable() ? Collections.unmodifiableMap( map ) : map;
068  }
069
070  /**
071   * Wrap specified list with unmodifiable list if and only if {@link Arez#areCollectionsPropertiesUnmodifiable()}
072   * returns true, otherwise return the supplied list. This method is invoked by the generated code when it detects
073   * list properties and should be used by repository extensions when returning list results.
074   *
075   * @param <T>  the type of elements in collection.
076   * @param list the input collection.
077   * @return the output collection.
078   */
079  @Nonnull
080  public static <T> List<T> wrap( @Nonnull final List<T> list )
081  {
082    return Arez.areCollectionsPropertiesUnmodifiable() ? Collections.unmodifiableList( list ) : list;
083  }
084
085  /**
086   * Convert specified stream to a list, wrapping as an unmodifiable list if required.
087   * This method should be called by repository extensions when returning list results.
088   *
089   * @param <T>    the type of elements in stream.
090   * @param stream the input stream.
091   * @return the output list
092   */
093  @Nonnull
094  public static <T> List<T> asList( @Nonnull final Stream<T> stream )
095  {
096    return wrap( stream.collect( Collectors.toList() ) );
097  }
098}