1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
package Torello.Java;

import java.util.function.Consumer;
import java.util.function.Supplier;

/**
 * Provides any method the ability to provide its users the ability to choose what kind of data
 * structure should be used for returning the method's results.  Currently, this class is used as 
 * a helper class for class {@link FileNode}
 * 
 * @param <INSERT_TYPE> Currently, the only class using {@code VarType} is class {@link FileNode}.
 * Within class {@link FileNode}, this Type-Parameter, {@code 'INSERT_TYPE'}, is always assigned
 * the value of class {@code 'FileNode'}
 * 
 * @param <RET_DATA_STRUCTURE> This Generic Type-Parameter provides a user the ability to specify
 * any Method Return-Type needed / desired.  In class {@link FileNode}, for instance, this
 * Type-Parameter is often assigned to things such as: {@code Stream<FileNode>},
 * {@code Iterator<FileNode>} or even {@code String[]} - where each of the {@code String's} are
 * actual File-Names as a {@code String}.
 * 
 * <BR /><BR />If this class {@code VarType} where used elsewhere, outside of {@code FileNode},
 * then the Generic Type-Parameter {@code 'RET_DATA_STRUCTURE'} would allow a user to provide a
 * means for his / her users to specify, exactly, any method's Return Type/Class.
 * 
 * @see FileNode
 */
public class VarType<RET_DATA_STRUCTURE, INSERT_TYPE>
{
    /** Accepts and inserts data into the data-structure. */
    public final Consumer<INSERT_TYPE> inserter;

    /** Performs any finalizations on the data-structure, and then returns it */
    public final Supplier<RET_DATA_STRUCTURE> finisher;

    // Identifies whether this instance has already been run to completion
    private boolean finished = false;

    /** Identifies whether this is a "Reusable" instance */
    public final boolean isReusable;

    /**
     * Constructs an instance of this class
     * @param inserter This is assigned to the field {@link #inserter}.
     * @param finisher Assigned to field {@link #finisher}.
     */
    public VarType(
            final Consumer<INSERT_TYPE>         inserter,
            final Supplier<RET_DATA_STRUCTURE>  finisher,
            final boolean                       isReusable
        )
    {
        if (isReusable)
        {
            this.isReusable = true;
            this.inserter   = inserter;
            this.finisher   = finisher;
        }

        else
        {
            this.isReusable = false;

            this.inserter = (INSERT_TYPE data) ->
            {
                if (this.finished) throw new VarTypeAlreadyUsedException();
                inserter.accept(data);
            };

            this.finisher = () ->
            {
                if (this.finished) throw new VarTypeAlreadyUsedException();
                this.finished = true;
                return finisher.get();
            };
        }
    }
}