View Javadoc
1   package dev.sympho.modular_commands.api.command;
2   
3   import java.util.Arrays;
4   import java.util.Iterator;
5   import java.util.List;
6   import java.util.Objects;
7   import java.util.Spliterator;
8   import java.util.stream.Stream;
9   
10  import org.apache.commons.collections4.ListUtils;
11  import org.checkerframework.dataflow.qual.Pure;
12  import org.checkerframework.dataflow.qual.SideEffectFree;
13  
14  /**
15   * An invocation of a command. That is, a sequence of keys (names) that (possibly) map
16   * to a command in the system.
17   *
18   * @param chain The invocation chain, the sequence of keys that forms the invocation.
19   * @version 1.0
20   * @since 1.0
21   */
22  public record Invocation( List<String> chain ) implements Iterable<String> {
23  
24      /** The empty invocation. */
25      public static final Invocation EMPTY = Invocation.of();
26  
27      /**
28       * Constructs an invocation determined by the given chain.
29       *
30       * @param chain The invocation chain.
31       */
32      @Pure
33      public Invocation( final List<String> chain ) {
34  
35          chain.forEach( c -> Objects.requireNonNull( c, 
36                  "Invocation chain cannot contain null." ) );
37          this.chain = List.copyOf( chain );
38  
39      }
40  
41      /**
42       * Determines the invocation formed by adding the given command name to
43       * this invocation.
44       *
45       * @param command The child command to invoke.
46       * @return The invocation of the child command.
47       */
48      @Pure
49      public Invocation child( final String command ) {
50  
51          final var childChain = List.of( 
52                  Objects.requireNonNull( command, "Command cannot be null." ) 
53          );
54          return new Invocation( ListUtils.union( chain, childChain ) );
55  
56      }
57  
58      /**
59       * Determines the parent invocation of this chain.
60       *
61       * @return The invocation of the parent command.
62       */
63      @Pure
64      public Invocation parent() {
65  
66          return new Invocation( chain.subList( 0, chain.size() - 1 ) );
67  
68      }
69  
70      /**
71       * Constructs an invocation from the given sequence of command names.
72       *
73       * @param commands The command names.
74       * @return The constructed invocation.
75       */
76      @Pure
77      public static Invocation of( final List<String> commands ) {
78  
79          return new Invocation( commands );
80  
81      }
82  
83      /**
84       * Constructs an invocation from the given sequence of command names.
85       *
86       * @param commands The command names.
87       * @return The constructed invocation.
88       */
89      @Pure
90      public static Invocation of( final String... commands ) {
91  
92          return of( Arrays.asList( commands ) );
93  
94      }
95  
96      @Override
97      public Iterator<String> iterator() {
98  
99          return chain.iterator();
100 
101     }
102 
103     @Override
104     public Spliterator<String> spliterator() {
105         
106         return chain.spliterator();
107 
108     }
109 
110     /**
111      * Obtains a stream over the invocation elements.
112      *
113      * @return The stream.
114      */
115     @SideEffectFree
116     public Stream<String> stream() {
117         
118         return chain.stream();
119 
120     }
121     
122 }