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 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 | package Torello.Java; import Torello.Java.StrFilter; import java.util.function.Predicate; import java.util.Iterator; /** * A simple functional-interface (lambda) for filtering lists of <CODE>FileNode</CODE>. * * <EMBED CLASS='external-html' DATA-FILE-ID=FILENODE_FILTER> * * @see StrFilter */ @FunctionalInterface public interface FileNodeFilter extends Predicate<FileNode>, java.io.Serializable { /** <EMBED CLASS='external-html' DATA-FILE-ID=SVUIDFI> */ public static final long serialVersionUID = 1; /** * <EMBED CLASS='external-html' DATA-FILE-ID=FUNC_INTER_METH> * * @param fn Any file node * * @return A {@code TRUE} value should mean that the {@code FileNode} has passed the test * (will be kept / retained). A return value of {@code FALSE} should indicate that the * {@code FileNode} needs to be filtered. */ public boolean test(FileNode fn); /** * Standard Java-{@code Predicate}, Java Functional-Interface AND routine. * * <BR /><BR />Logically AND's <B>{@code 'this'}</B> {@code FileNodeFilter} with the filter * parameter <B>{@code 'other'}</B> * * @param other A 2nd {@code FileNodeFilter} with which <B>{@code 'this'}</B> filter may be * AND'ed. * * @return A new {@code FileNodeFilter} that is the logical-and of <B>{@code 'this'}</B> filter * and <B>{@code 'other'}</B> */ default FileNodeFilter and(FileNodeFilter other) { // FAIL-FAST: Check that the lambda will not throw a null pointer exception prior to // creating the lambda. if (other == null) throw new NullPointerException ("The parameter 'other' to FileNodeFilter.and(other) was null."); return (FileNode f) -> this.test(f) && other.test(f); } /** * Standard Java-{@code Predicate}, Java Functional-Interface OR routine. * * <BR /><BR />Logically OR's <B>{@code 'this'}</B> {@code FileNodeFilter} with the filter * parameter <B>{@code 'other'}</B> * * @param other A 2nd {@code FileNodeFilter} with which <B>{@code 'this'}</B> filter may be * or'ed. * * @return A new FileNodeFilter that is the logical-or of <B>{@code 'this'}</B> filter and * <B>"other"</B> */ default FileNodeFilter or(FileNodeFilter other) { // FAIL-FAST: Check that the lambda will not throw a null pointer exception prior to // creating the lambda. if (other == null) throw new NullPointerException ("The parameter 'other' to FileNodeFilter.or(other) was null.."); return (FileNode f) -> this.test(f) || other.test(f); } /** * Standard Java-{@code Predicate}, Java Functional-Interface NEGATE routine. * * <BR /><BR />Generates 's a {@code FileNodeFilter} that is the "logical-not" of * <B>{@code 'this'}</B> filter. * * @return A new {@code FileNodeFilter} that would return {@code TRUE} whenever * <B>{@code 'this'}</B> would return {@code FALSE}, and vice-versa. */ default FileNodeFilter negate() { return (FileNode f) -> ! this.test(f); } /** * This is similar to the java streams function {@code filter(Predicate<>)}. Elements that do * not meet the criteria specified by this {@code FileNodeFilter} - <I>specifically, if an * element of the input-parameter {@code 'urlList'} would evaluate to {@code FALSE}</I> - then * that element shall be removed from the list. * * @param fileNodes An {@code Iterable} of {@code FileNode's} which the user would like * filtered using {@code 'this'} filter. * * @return The number of elements that were removed from parameter {@code 'fileNodes'} based on * the results of the {@code 'test(FileNode)'} lambda-method {@code FileNodeFilter.test()} of * {@code 'this'} instance. */ public default int filter(Iterable<FileNode> fileNodes) { int removeCount = 0; Iterator<FileNode> iter = fileNodes.iterator(); // If the filter test returns FALSE, then remove the URL from the collection. // Increment the removeCount Counter. while (iter.hasNext()) if (! test(iter.next())) { removeCount++; iter.remove(); } return removeCount; } /** * This wraps a {@code StrFilter} inside of a {@code FileNodeFilter}. The * {@code String}-comparison that is performed will use the full-path-name of the * {@code FileNode}. * * @param sf This is a "String Predicate" that has (usually, but not required) been built by * one of the many {@code String}-Filter Factory-Build static-methods of * {@code class StrFilter}. The Predicate's that are constructed via the build methods of * {@code StrFilter} call the {@code Object.toString()} method on the objects they receive for * testing. * * @return FileNodeFilter This will return an instance of a {@code FileNodeFilter} that will * test the full-path-name as a {@code String}. * * @see StrFilter */ public static FileNodeFilter fromStrFilter(StrFilter sf) { if (sf == null) throw new NullPointerException( "The String-Filter Predicate Parameter 'sf' in static-factory builder method " + "'fromStrFilter' was passed a null value." ); return (FileNode fn) -> sf.test(fn); } } |