checkstyle

This commit is contained in:
jendave
2011-10-26 19:54:25 +00:00
parent d12136f714
commit c8140b3c2e
9 changed files with 502 additions and 436 deletions

View File

@@ -34,7 +34,6 @@ import forge.quest.gui.main.QuestChallenge;
import forge.quest.gui.main.QuestEvent; import forge.quest.gui.main.QuestEvent;
import forge.view.swing.WinLoseModeHandler; import forge.view.swing.WinLoseModeHandler;
// TODO: Auto-generated Javadoc
/** /**
* <p> * <p>
* QuestWinLoseHandler. * QuestWinLoseHandler.

View File

@@ -37,7 +37,7 @@ public class WinLoseModeHandler {
* Action performed when "quit" button is pressed in default win/lose UI. * Action performed when "quit" button is pressed in default win/lose UI.
* *
*/ */
public final void actionOnQuit() { public void actionOnQuit() {
if (System.getenv("NG2") != null) { if (System.getenv("NG2") != null) {
if (System.getenv("NG2").equalsIgnoreCase("true")) { if (System.getenv("NG2").equalsIgnoreCase("true")) {
String[] argz = {}; String[] argz = {};
@@ -69,7 +69,7 @@ public class WinLoseModeHandler {
* with other game modes. * with other game modes.
* *
*/ */
public final void startNextRound() { public void startNextRound() {
AllZone.getGameAction().newGame(Constant.Runtime.HumanDeck[0], Constant.Runtime.ComputerDeck[0]); AllZone.getGameAction().newGame(Constant.Runtime.HumanDeck[0], Constant.Runtime.ComputerDeck[0]);
} }
@@ -82,7 +82,7 @@ public class WinLoseModeHandler {
* *
* @return true, if successful * @return true, if successful
*/ */
public final boolean populateCustomPanel() { public boolean populateCustomPanel() {
return false; return false;
} }

View File

@@ -4,5 +4,12 @@ package net.slightlymagic.braids.util;
* Like Runnable, but it can throw any Exception. * Like Runnable, but it can throw any Exception.
*/ */
public interface ClumsyRunnable { public interface ClumsyRunnable {
public void run() throws Exception;
/**
* Run.
*
* @throws Exception
* the exception
*/
void run() throws Exception;
} }

View File

@@ -5,56 +5,66 @@ import java.util.Iterator;
/** /**
* Acts as both immutable Iterator and Iterable; remove method always throws * Acts as both immutable Iterator and Iterable; remove method always throws
* exception. * exception.
*
* @param <T>
* the generic type
*/ */
public class ImmutableIterableFrom<T> implements Iterable<T>, Iterator<T> { public class ImmutableIterableFrom<T> implements Iterable<T>, Iterator<T> {
private Iterator<T> iterator; private Iterator<T> iterator;
/** /**
* Wrap an iterable so that it cannot be changed via * Wrap an iterable so that it cannot be changed via the remove method.
* the remove method. *
* * @param iterable
* @param iterable the iterable to wrap * the iterable to wrap
*/ */
public ImmutableIterableFrom(Iterable<T> iterable) { public ImmutableIterableFrom(final Iterable<T> iterable) {
this.iterator = iterable.iterator(); this.iterator = iterable.iterator();
} }
/** /**
* Wrap an iterator so that its container cannot be changed via * Wrap an iterator so that its container cannot be changed via the remove
* the remove method. * method.
* *
* @param iterator the iterator to wrap * @param iterator
*/ * the iterator to wrap
public ImmutableIterableFrom(Iterator<T> iterator) { */
this.iterator = iterator; public ImmutableIterableFrom(final Iterator<T> iterator) {
} this.iterator = iterator;
}
/** /**
* This class acts as both an Iterable and an Iterator. * This class acts as both an Iterable and an Iterator.
*/ *
public Iterator<T> iterator() { * @return the iterator
return this; */
} public final Iterator<T> iterator() {
return this;
}
/** /**
* Returns hasNext from the wrapped [object's] iterator. * Returns hasNext from the wrapped [object's] iterator.
*/ *
public boolean hasNext() { * @return true, if successful
return iterator.hasNext(); */
} public final boolean hasNext() {
return iterator.hasNext();
}
/** /**
* Returns next from the wrapped [object's] iterator. * Returns next from the wrapped [object's] iterator.
*/ *
public T next() { * @return the t
return iterator.next(); */
} public final T next() {
return iterator.next();
}
/** /**
* Never succeeeds. * Never succeeeds.
* @throws UnsupportedOperationException always. *
*/ */
public void remove() { public final void remove() {
throw new UnsupportedOperationException(); throw new UnsupportedOperationException();
} }
} }

View File

@@ -23,9 +23,10 @@ public class NotImplementedError extends RuntimeException {
/** /**
* Indicates what has not been implemented. * Indicates what has not been implemented.
* *
* @param message indicates what exactly has not been implemented. * @param message
* May include information about future plans to implement the described * indicates what exactly has not been implemented. May include
* section of code. * information about future plans to implement the described
* section of code.
*/ */
public NotImplementedError(final String message) { public NotImplementedError(final String message) {
super(message); super(message);
@@ -34,7 +35,8 @@ public class NotImplementedError extends RuntimeException {
/** /**
* Like the no-arg constructor, but with a cause parameter. * Like the no-arg constructor, but with a cause parameter.
* *
* @param cause the exception that caused this one to be thrown * @param cause
* the exception that caused this one to be thrown
* *
* @see #NotImplementedError() * @see #NotImplementedError()
*/ */
@@ -45,11 +47,13 @@ public class NotImplementedError extends RuntimeException {
/** /**
* Like the String constructor, but with a cause parameter. * Like the String constructor, but with a cause parameter.
* *
* @param message indicates what exactly has not been implemented. * @param message
* May include information about future plans to implement the described * indicates what exactly has not been implemented. May include
* section of code. * information about future plans to implement the described
* section of code.
* *
* @param cause the exception that caused this one to be thrown * @param cause
* the exception that caused this one to be thrown
* *
* @see #NotImplementedError(String) * @see #NotImplementedError(String)
*/ */

View File

@@ -19,12 +19,13 @@ public final class UtilFunctions {
// empty // empty
} }
/** /**
* Throws a NullPointerException if param is null. * Throws a NullPointerException if param is null.
* *
* @param paramName the name of the parameter; may be null * @param paramName
* @param param the parameter to test * the name of the parameter; may be null
* @param param
* the parameter to test
*/ */
public static void checkNotNull(final String paramName, final Object param) { public static void checkNotNull(final String paramName, final Object param) {
if (param != null) { if (param != null) {
@@ -34,10 +35,16 @@ public final class UtilFunctions {
NullPointerException exn = null; NullPointerException exn = null;
if (paramName == null) { if (paramName == null) {
exn = new NullPointerException(); // NOPMD by Braids on 8/18/11 11:19 PM exn = new NullPointerException(); // NOPMD by Braids on 8/18/11
} // 11:19 PM
else { } else {
exn = new NullPointerException(paramName + " must not be null"); // NOPMD by Braids on 8/18/11 11:19 PM exn = new NullPointerException(paramName + " must not be null"); // NOPMD
// by
// Braids
// on
// 8/18/11
// 11:19
// PM
} }
// Doctor the exception to appear to come from the caller. // Doctor the exception to appear to come from the caller.
@@ -48,42 +55,51 @@ public final class UtilFunctions {
} }
/** /**
* Invoke the given Runnable in an Event Dispatch Thread and wait for it * Invoke the given Runnable in an Event Dispatch Thread and wait for it to
* to finish; but <B>try to use SwingUtilities.invokeLater instead whenever * finish; but <B>try to use SwingUtilities.invokeLater instead whenever
* feasible.</B> * feasible.</B>
* *
* Exceptions generated by SwingUtilities.invokeAndWait (if used), are * Exceptions generated by SwingUtilities.invokeAndWait (if used), are
* rethrown as RuntimeExceptions. * rethrown as RuntimeExceptions.
* *
* @param proc
* the Runnable to run
* @see javax.swing.SwingUtilities#invokeLater(Runnable) * @see javax.swing.SwingUtilities#invokeLater(Runnable)
*
* @param proc the Runnable to run
*/ */
public static void invokeInEventDispatchThreadAndWait(final Runnable proc) { // NOPMD by Braids on 8/18/11 11:19 PM public static void invokeInEventDispatchThreadAndWait(final Runnable proc) { // NOPMD
// by
// Braids
// on
// 8/18/11
// 11:19
// PM
if (SwingUtilities.isEventDispatchThread()) { if (SwingUtilities.isEventDispatchThread()) {
// Just run in the current thread. // Just run in the current thread.
proc.run(); proc.run();
} } else {
else {
try { try {
SwingUtilities.invokeAndWait(proc); SwingUtilities.invokeAndWait(proc);
} catch (InterruptedException exn) { } catch (InterruptedException exn) {
throw new RuntimeException(exn); // NOPMD by Braids on 8/18/11 11:19 PM throw new RuntimeException(exn); // NOPMD by Braids on 8/18/11
// 11:19 PM
} catch (InvocationTargetException exn) { } catch (InvocationTargetException exn) {
throw new RuntimeException(exn); // NOPMD by Braids on 8/18/11 11:19 PM throw new RuntimeException(exn); // NOPMD by Braids on 8/18/11
// 11:19 PM
} }
} }
} }
/** /**
* Create an array from the (rest of) an iterator's output; * Create an array from the (rest of) an iterator's output; this function is
* this function is horribly inefficient. * horribly inefficient.
* *
* Please, only use it on small iterators. * Please, only use it on small iterators.
* *
* @param <T> (inferred automatically) * @param <T>
* (inferred automatically)
* *
* @param iter the iterator to traverse * @param iter
* the iterator to traverse
* *
* @return an array of (the rest of) the iterator's values * @return an array of (the rest of) the iterator's values
*/ */
@@ -101,27 +117,28 @@ public final class UtilFunctions {
return result; return result;
} }
/** /**
* Returns the rightmost portion of an array, Python-style. * Returns the rightmost portion of an array, Python-style.
* *
* @param <T> (inferred automatically) * @param <T>
* (inferred automatically)
* *
* @param dstArray the array in which to place new items * @param dstArray
* the array in which to place new items
* *
* @param srcArray the array to copy (shallowly) * @param srcArray
* the array to copy (shallowly)
* *
* @param startIndexIn if positive, the index (from the left) at which to * @param startIndexIn
* start copying; if negative, we treat this as the index from the right. * if positive, the index (from the left) at which to start
* For example, calling this with startIndex = -2 returns the last two * copying; if negative, we treat this as the index from the
* items in the array, if it has that many. * right. For example, calling this with startIndex = -2 returns
* the last two items in the array, if it has that many.
* *
* @return a shallow copy of array starting at startIndex; this may return * @return a shallow copy of array starting at startIndex; this may return
* an empty array if the startIndex is out of bounds. * an empty array if the startIndex is out of bounds.
*/ */
public static <T extends Object> T[] slice(final T[] dstArray, final T[] srcArray, public static <T extends Object> T[] slice(final T[] dstArray, final T[] srcArray, final int startIndexIn) {
final int startIndexIn)
{
int startIndex = startIndexIn; int startIndex = startIndexIn;
if (startIndex < 0) { if (startIndex < 0) {
startIndex = srcArray.length + startIndex; startIndex = srcArray.length + startIndex;
@@ -131,55 +148,51 @@ public final class UtilFunctions {
} }
if (dstArray == null) { if (dstArray == null) {
throw new NullPointerException(); // NOPMD by Braids on 8/18/11 11:19 PM throw new NullPointerException(); // NOPMD by Braids on 8/18/11
// 11:19 PM
} }
if (srcArray == null) { if (srcArray == null) {
throw new NullPointerException(); // NOPMD by Braids on 8/18/11 11:19 PM throw new NullPointerException(); // NOPMD by Braids on 8/18/11
// 11:19 PM
} }
final int resultLength = getSliceLength(srcArray, startIndex); final int resultLength = getSliceLength(srcArray, startIndex);
if (dstArray.length != resultLength) { if (dstArray.length != resultLength) {
throw new ArrayIndexOutOfBoundsException( throw new ArrayIndexOutOfBoundsException("First parameter must have length " + resultLength
"First parameter must have length " + resultLength
+ ", but length is " + dstArray.length + "."); + ", but length is " + dstArray.length + ".");
} }
int srcIx = startIndex; int srcIx = startIndex;
for (int dstIx = 0; for (int dstIx = 0; dstIx < resultLength && srcIx < srcArray.length; dstIx++, srcIx++) {
dstIx < resultLength && srcIx < srcArray.length;
dstIx++, srcIx++)
{
dstArray[dstIx] = srcArray[srcIx]; dstArray[dstIx] = srcArray[srcIx];
} }
return dstArray; return dstArray;
} }
/** /**
* Get a slice's length in preparation for taking a slice. * Get a slice's length in preparation for taking a slice.
* *
* I do not like the fact that I have to use this function, but * I do not like the fact that I have to use this function, but Java left me
* Java left me with little choice. * with little choice.
*
* @see #slice(Object[], Object[], int)
*
* @param <T> (inferred automatically)
*
* @param srcArray the array that would be copied (shallowly)
*
* @param startIndexIn if positive, the index (from the left) at which
* copying would start; if negative, we treat this as the index from the
* right. For example, calling this with startIndex = -2 computes the
* length if slice would return the last two items in the array, if it has
* that many.
* *
* @param <T>
* (inferred automatically)
* @param srcArray
* the array that would be copied (shallowly)
* @param startIndexIn
* if positive, the index (from the left) at which copying would
* start; if negative, we treat this as the index from the right.
* For example, calling this with startIndex = -2 computes the
* length if slice would return the last two items in the array,
* if it has that many.
* @return the length of the array that would result from calling * @return the length of the array that would result from calling
* slice(Object[], Object[], int) with the given srcArray and * slice(Object[], Object[], int) with the given srcArray and
* startIndex. * startIndex.
* @see #slice(Object[], Object[], int)
*/ */
public static <T> int getSliceLength(final T[] srcArray, final int startIndexIn) { public static <T> int getSliceLength(final T[] srcArray, final int startIndexIn) {
int startIndex = startIndexIn; int startIndex = startIndexIn;
@@ -195,34 +208,43 @@ public final class UtilFunctions {
return resultLength; return resultLength;
} }
/** /**
* Handles the boilerplate null and isinstance check for an equals method. * Handles the boilerplate null and isinstance check for an equals method.
* *
* Example: * Example:
*
* <pre> * <pre>
* public boolean equals(Object obj) { * public boolean equals(Object obj) {
* MyClassName that = checkNullOrNotInstance(this, obj); * MyClassName that = checkNullOrNotInstance(this, obj);
* if (that == null) { * if (that == null) {
* return false; * return false;
* } * }
* //... * // ...
* } * }
* </pre> * </pre>
* *
* @param <T> (inferred automatically) * @param <T>
* (inferred automatically)
* *
* @param goodInstance a non-null instance of type T; looks neater than * @param goodInstance
* passing in goodInstance.getClass() * a non-null instance of type T; looks neater than passing in
* goodInstance.getClass()
* *
* @param obj the object to test * @param obj
* the object to test
* *
* @return null if obj is null or not an instance of goodInstance's class; * @return null if obj is null or not an instance of goodInstance's class;
* otherwise, we return obj cast to goodInstance's type * otherwise, we return obj cast to goodInstance's type
*/ */
public static <T> T checkNullOrNotInstance(final T goodInstance, final Object obj) { public static <T> T checkNullOrNotInstance(final T goodInstance, final Object obj) {
if (goodInstance == null) { if (goodInstance == null) {
throw new NullPointerException("first parameter must not be null"); // NOPMD by Braids on 8/18/11 11:19 PM throw new NullPointerException("first parameter must not be null"); // NOPMD
// by
// Braids
// on
// 8/18/11
// 11:19
// PM
} }
@SuppressWarnings("unchecked") @SuppressWarnings("unchecked")
@@ -246,12 +268,11 @@ public final class UtilFunctions {
return result; return result;
} }
/** /**
* Safely converts an object to a String. * Safely converts an object to a String.
* *
* @param obj to convert; may be null * @param obj
* to convert; may be null
* *
* @return "null" if obj is null, obj.toString() otherwise * @return "null" if obj is null, obj.toString() otherwise
*/ */
@@ -260,8 +281,7 @@ public final class UtilFunctions {
if (obj == null) { if (obj == null) {
result = "null"; result = "null";
} } else {
else {
result = obj.toString(); result = obj.toString();
} }
@@ -275,28 +295,28 @@ public final class UtilFunctions {
* determine equality. * determine equality.
* *
* Advantages over HashSet: This consumes no unnecessary heap-memory, nor * Advantages over HashSet: This consumes no unnecessary heap-memory, nor
* does it require objects to implement hashCode. It is OK if * does it require objects to implement hashCode. It is OK if (o1.equals(o2)
* (o1.equals(o2) does not imply o1.hashCode() == o2.hashCode()). * does not imply o1.hashCode() == o2.hashCode()).
* *
* Advantages over TreeSet: This does not require a comparator. * Advantages over TreeSet: This does not require a comparator.
* *
* Disadvantages over HashSet and TreeSet: This runs in O(n*n) time. * Disadvantages over HashSet and TreeSet: This runs in O(n*n) time.
* *
* @param <T> (inferred automatically) * @param <T>
* (inferred automatically)
* *
* @param list the list to modify; this is fastest with ArrayList. * @param list
* the list to modify; this is fastest with ArrayList.
*/ */
public static <T> void smartRemoveDuplicatesAndNulls(final List<T> list) { public static <T> void smartRemoveDuplicatesAndNulls(final List<T> list) {
// Get rid of pesky leading nulls. // Get rid of pesky leading nulls.
smartRemoveDuplicatesAndNullsHelper(list, 0, null); smartRemoveDuplicatesAndNullsHelper(list, 0, null);
for (int earlierIx = 0; earlierIx < list.size(); earlierIx++) { for (int earlierIx = 0; earlierIx < list.size(); earlierIx++) {
for (int laterIx = earlierIx + 1; laterIx < list.size(); laterIx++) for (int laterIx = earlierIx + 1; laterIx < list.size(); laterIx++) {
{
final T itemAtEarlierIx = list.get(earlierIx); final T itemAtEarlierIx = list.get(earlierIx);
smartRemoveDuplicatesAndNullsHelper(list, laterIx, smartRemoveDuplicatesAndNullsHelper(list, laterIx, itemAtEarlierIx);
itemAtEarlierIx);
} }
} }
@@ -304,28 +324,25 @@ public final class UtilFunctions {
/** /**
* Helper method for smartRemoveDuplicatesAndNulls that is subject to * Helper method for smartRemoveDuplicatesAndNulls that is subject to
* change; if you call this directly, you do so at your own risk! * change; if you call this directly, you do so at your own risk!.
* *
* @param <T> (inferred automatically) * @param <T>
* * (inferred automatically)
* @param list the list to modify; if all items from startIx to the end * @param list
* are either null or equal to objSeenPreviously, then we truncate the * the list to modify; if all items from startIx to the end are
* list just before startIx. * either null or equal to objSeenPreviously, then we truncate
* * the list just before startIx.
* @param startIx the index to examine; we only move items within the range * @param startIx
* of [startIx, list.size()-1]. * the index to examine; we only move items within the range of
* * [startIx, list.size()-1].
* @param objSeenPreviously the object with which to compare list[startIx]; * @param objSeenPreviously
* may be null. * the object with which to compare list[startIx]; may be null.
*/ */
public static <T> void smartRemoveDuplicatesAndNullsHelper( public static <T> void smartRemoveDuplicatesAndNullsHelper(final List<T> list, final int startIx,
final List<T> list, final int startIx, final T objSeenPreviously) final T objSeenPreviously) {
{
while (startIx < list.size() while (startIx < list.size()
&& (list.get(startIx) == null && (list.get(startIx) == null || list.get(startIx) == objSeenPreviously || list.get(startIx).equals(
|| list.get(startIx) == objSeenPreviously objSeenPreviously))) {
|| list.get(startIx).equals(objSeenPreviously)))
{
final int lastItemIx = list.size() - 1; final int lastItemIx = list.size() - 1;
// Overwrite the item at laterIx with the one at the end, // Overwrite the item at laterIx with the one at the end,

View File

@@ -1,61 +1,69 @@
/** Licensed under both the GPL and the Apache 2.0 License. */ /** Licensed under both the GPL and the Apache 2.0 License. */
package net.slightlymagic.braids.util.generator; package net.slightlymagic.braids.util.generator;
import java.io.File;
import com.google.code.jyield.Generator; import com.google.code.jyield.Generator;
import com.google.code.jyield.Yieldable; import com.google.code.jyield.Yieldable;
import java.io.File;
/** /**
* This is a generator over all of the non-directories residing in a given * This is a generator over all of the non-directories residing in a given
* starting directory and all subdirectories of it that do NOT start with a * starting directory and all subdirectories of it that do NOT start with a dot;
* dot; this prevents the code from descending into .svn directories. * this prevents the code from descending into .svn directories.
* *
* For documentation on Java-Yield and its generators, see * For documentation on Java-Yield and its generators, see
* {@link com.google.code.jyield.Generator} * {@link com.google.code.jyield.Generator}
*/ */
public class FindNonDirectoriesSkipDotDirectoriesGenerator implements Generator<File> { public class FindNonDirectoriesSkipDotDirectoriesGenerator implements Generator<File> {
private File startDir; private File startDir;
/** /**
* Create a generator at a given starting directory. * Create a generator at a given starting directory.
* *
* One can invoke this generator more than once by calling its generate * One can invoke this generator more than once by calling its generate
* method. * method.
* *
* @param startDir the directory to start in; we ignore this directory's * @param startDir
* name, so if it starts with a dot, we treat it as if it didn't. * the directory to start in; we ignore this directory's name, so
*/ * if it starts with a dot, we treat it as if it didn't.
public FindNonDirectoriesSkipDotDirectoriesGenerator(File startDir) { */
this.startDir = startDir; public FindNonDirectoriesSkipDotDirectoriesGenerator(final File startDir) {
} this.startDir = startDir;
}
/** /**
* Standard generate method. * Standard generate method.
* *
* <p>Yields results to the given Yieldable. Convert Generator instances to * <p>
* Iterables with YieldUtils.toIterable.</p> * Yields results to the given Yieldable. Convert Generator instances to
* * Iterables with YieldUtils.toIterable.
* See {@link com.google.code.jyield.YieldUtils#toIterable(com.google.code.jyield.Generator)} * </p>
*/ *
public void generate(Yieldable<File> yy) { * See
String[] list = startDir.list(); * {@link com.google.code.jyield.YieldUtils#toIterable(com.google.code.jyield.Generator)}
*
* @param yy
* the yy
*/
public final void generate(final Yieldable<File> yy) {
String[] list = startDir.list();
for (String filename : list) { for (String filename : list) {
File entry = new File(startDir, filename); File entry = new File(startDir, filename);
if (entry.isDirectory()) { if (entry.isDirectory()) {
if (!filename.startsWith(".")) { if (!filename.startsWith(".")) {
FindNonDirectoriesSkipDotDirectoriesGenerator child = new FindNonDirectoriesSkipDotDirectoriesGenerator(entry); FindNonDirectoriesSkipDotDirectoriesGenerator child =
child.generate(yy); new FindNonDirectoriesSkipDotDirectoriesGenerator(
child = null; entry);
} child.generate(yy);
// else do nothing, because it's a dot directory child = null;
} }
else { // else do nothing, because it's a dot directory
// Use this instead of a return statement. } else {
yy.yield(entry); // Use this instead of a return statement.
} yy.yield(entry);
} }
} }
}
} }

View File

@@ -4,33 +4,43 @@ import com.google.code.jyield.Generator;
import com.google.code.jyield.Yieldable; import com.google.code.jyield.Yieldable;
/** /**
* Creates a Generator from an array; generators are a handy * Creates a Generator from an array; generators are a handy substitute for
* substitute for passing around and creating temporary * passing around and creating temporary lists, collections, and arrays.
* lists, collections, and arrays.
* *
* {@link com.google.code.jyield.Generator} * @param <T>
* the generic type {@link com.google.code.jyield.Generator}
*/ */
public class GeneratorFromArray<T> implements Generator<T> { public class GeneratorFromArray<T> implements Generator<T> {
private T[] array; private T[] array;
/** /**
* Create a Generator from an array * Create a Generator from an array.
* *
* @param array from which to generate items * @param array
*/ * from which to generate items
public GeneratorFromArray(T[] array) { */
this.array = array; public GeneratorFromArray(final T[] array) {
} this.array = array;
}
@Override /*
/** * (non-Javadoc)
* Submits all of the array's elements to the yieldable. *
* * @see
* @param yy the yieldable which receives the elements * com.google.code.jyield.Generator#generate(com.google.code.jyield.Yieldable
*/ * )
public void generate(Yieldable<T> yy) { */
for (T item : array) {
yy.yield(item); /**
} * Submits all of the array's elements to the yieldable.
} *
* @param yy
* the yieldable which receives the elements
*/
@Override
public final void generate(final Yieldable<T> yy) {
for (T item : array) {
yy.yield(item);
}
}
} }

View File

@@ -1,204 +1,215 @@
/** Licensed under both the GPL and the Apache 2.0 License. */ /** Licensed under both the GPL and the Apache 2.0 License. */
package net.slightlymagic.braids.util.generator; package net.slightlymagic.braids.util.generator;
import com.google.code.jyield.Generator;
import com.google.code.jyield.YieldUtils;
import com.google.code.jyield.Yieldable;
import net.slightlymagic.braids.util.lambda.Lambda1;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.NoSuchElementException; import java.util.NoSuchElementException;
import net.slightlymagic.braids.util.lambda.Lambda1;
import com.google.code.jyield.Generator;
import com.google.code.jyield.YieldUtils;
import com.google.code.jyield.Yieldable;
/** /**
* For documentation on Java-Yield and its generators, see * For documentation on Java-Yield and its generators, see.
*
* {@link com.google.code.jyield.Generator}. * {@link com.google.code.jyield.Generator}.
*/ */
public final class GeneratorFunctions { public final class GeneratorFunctions {
/** /**
* Do not instantiate. * Do not instantiate.
*/ */
private GeneratorFunctions() { private GeneratorFunctions() {
; }
}
/** /**
* Estimate the number of items in this generator by traversing all of its * Estimate the number of items in this generator by traversing all of its
* elements. * elements.
* *
* Note this only works on a generator that can be reinstantiated once it * Note this only works on a generator that can be reinstantiated once it
* has been traversed. This is only an estimate, because a generator's size * has been traversed. This is only an estimate, because a generator's size
* may vary been traversals. This is especially true if the generator * may vary been traversals. This is especially true if the generator relies
* relies on external resources, such as a file system. * on external resources, such as a file system.
* *
* If you call this on an infinite generator, this method will never * If you call this on an infinite generator, this method will never return.
* return. *
* * @param <T>
* @return the estimated number of items provided by this generator * the generic type
*/ * @param gen
public static <T> long estimateSize(Generator<T> gen) { * the gen
long result = 0; * @return the estimated number of items provided by this generator
for (@SuppressWarnings("unused") T ignored : YieldUtils.toIterable(gen)) */
{ public static <T> long estimateSize(final Generator<T> gen) {
result++; long result = 0;
} for (@SuppressWarnings("unused")
T ignored : YieldUtils.toIterable(gen))
{
result++;
}
return result; return result;
} }
/** /**
* Highly efficient means of filtering a long or infinite sequence. * Highly efficient means of filtering a long or infinite sequence.
* *
* @param <T> any type * @param <T>
* * any type
* @param predicate a Lambda (function) whose apply method takes an object *
* of type <T> and returns a Boolean. If it returns false or null, the * @param predicate
* item from the inputGenerator is not yielded by this Generator; * a Lambda (function) whose apply method takes an object of type
* if predicate.apply returns true, then this Generator <i>does</i> * <T> and returns a Boolean. If it returns false or null, the
* yield the value. * item from the inputGenerator is not yielded by this Generator;
* * if predicate.apply returns true, then this Generator
* @param inputGenerator the sequence upon which we operate * <i>does</i> yield the value.
* *
* @return a generator which produces a subset <= the inputGenerator * @param inputGenerator
*/ * the sequence upon which we operate
public static <T> Generator<T> filterGenerator( *
final Lambda1<Boolean,T> predicate, final Generator<T> inputGenerator) * @return a generator which produces a subset <= the inputGenerator
{ */
Generator<T> result = new Generator<T>() { public static <T> Generator<T> filterGenerator(final Lambda1<Boolean, T> predicate,
final Generator<T> inputGenerator)
{
Generator<T> result = new Generator<T>() {
@Override @Override
public void generate(final Yieldable<T> outputYield) { public void generate(final Yieldable<T> outputYield) {
Yieldable<T> inputYield = new Yieldable<T>() { Yieldable<T> inputYield = new Yieldable<T>() {
Boolean pResult; Boolean pResult;
@Override @Override
public void yield(T input) { public void yield(final T input) {
pResult = predicate.apply(input); pResult = predicate.apply(input);
if (pResult != null && pResult) { if (pResult != null && pResult) {
outputYield.yield(input); outputYield.yield(input);
} }
} }
}; };
inputGenerator.generate(inputYield); inputGenerator.generate(inputYield);
} }
}; };
return result; return result;
} }
/** /**
* Highly efficient means of applying a transform to a long or infinite * Highly efficient means of applying a transform to a long or infinite
* sequence. * sequence.
* *
* @param <T> any type * @param <T>
* * any type
* @param transform a Lambda (function) whose apply method takes an object *
* of type <T> and returns an object of the same type. This transforms * @param transform
* the values from the inputGenerator into this Generator. * a Lambda (function) whose apply method takes an object of type
* * <T> and returns an object of the same type. This transforms
* @param inputGenerator the sequence upon which we operate * the values from the inputGenerator into this Generator.
* *
* @return a generator that yields transform.apply's return value for * @param inputGenerator
* each item in the inputGenerator * the sequence upon which we operate
*/ *
public static <T> Generator<T> transformGenerator( * @return a generator that yields transform.apply's return value for each
final Lambda1<T,T> transform, final Generator<T> inputGenerator) * item in the inputGenerator
{ */
Generator<T> result = new Generator<T>() { public static <T> Generator<T> transformGenerator(final Lambda1<T, T> transform, final Generator<T> inputGenerator)
{
Generator<T> result = new Generator<T>() {
@Override @Override
public void generate(final Yieldable<T> outputYield) { public void generate(final Yieldable<T> outputYield) {
Yieldable<T> inputYield = new Yieldable<T>() { Yieldable<T> inputYield = new Yieldable<T>() {
@Override @Override
public void yield(T input) { public void yield(final T input) {
outputYield.yield(transform.apply(input)); outputYield.yield(transform.apply(input));
} }
}; };
inputGenerator.generate(inputYield); inputGenerator.generate(inputYield);
} }
}; };
return result; return result;
} }
/** /**
* Forces a generator to be completely evaluated into a temporary data * Forces a generator to be completely evaluated into a temporary data
* structure, then returns the generator over that same structure. * structure, then returns the generator over that same structure.
* *
* This effectively returns the same Generator, but it is a faster one. * This effectively returns the same Generator, but it is a faster one. This
* This trades away heap space for reduced CPU intensity. This is * trades away heap space for reduced CPU intensity. This is particuarly
* particuarly helpful if you know that a Generator is going to be * helpful if you know that a Generator is going to be totally evaluated
* totally evaluated more than once in the near future. * more than once in the near future.
* *
* @param <T> inferred automatically * @param <T>
* * inferred automatically
* @param unevaluated a Generator of T instances *
* * @param unevaluated
* @return the equivalent Generator, except that the result's generate * a Generator of T instances
* method can be invoked multiple times for fast results. *
*/ * @return the equivalent Generator, except that the result's generate
public static <T> Generator<T> solidify(Generator<T> unevaluated) { * method can be invoked multiple times for fast results.
*/
public static <T> Generator<T> solidify(final Generator<T> unevaluated) {
ArrayList<T> solidTmp = YieldUtils.toArrayList(unevaluated); ArrayList<T> solidTmp = YieldUtils.toArrayList(unevaluated);
solidTmp.trimToSize(); solidTmp.trimToSize();
return YieldUtils.toGenerator(solidTmp); return YieldUtils.toGenerator(solidTmp);
} }
/** /**
* Select an item at random from a Generator; this causes the entire * Select an item at random from a Generator; this causes the entire
* Generator to be evaluated once, but only once. * Generator to be evaluated once, but only once.
* *
* @param generator * @param <T>
* the generator from which to select a random item * the generic type
* * @param generator
* @return an item chosen at random from the generator; this may be null, if * the generator from which to select a random item
* the generator contains null items. * @return an item chosen at random from the generator; this may be null, if
* * the generator contains null items.
* @throws NoSuchElementException * @throws NoSuchElementException
* if the generator has no contents * if the generator has no contents
*/ */
public static <T> T selectRandom(Generator<T> generator) public static <T> T selectRandom(final Generator<T> generator) throws NoSuchElementException
throws NoSuchElementException {
{ /*
/* * This algorithm requires some explanation. Each time we encounter a
* This algorithm requires some explanation. Each time we encounter a * new item from the generator, we determine via random chance if the
* new item from the generator, we determine via random chance if the * item is the one we select. At the end of each iteration, we have a
* item is the one we select. At the end of each iteration, we have a * candidate, and we have a count of the number of items encountered so
* candidate, and we have a count of the number of items encountered so * far. Each iteration has a 1/n chance of replacing the candidate with
* far. Each iteration has a 1/n chance of replacing the candidate with * the current item, where n is the number of items encountered so far.
* the current item, where n is the number of items encountered so far. * This allows us to randomly select an item from the generated contents
* This allows us to randomly select an item from the generated contents * with an equal distribution; and we don't have to count the number of
* with an equal distribution; and we don't have to count the number of * items first!
* items first! */
*/
int n = 0; int n = 0;
T candidate = null; T candidate = null;
for (T item : YieldUtils.toIterable(generator)) { for (T item : YieldUtils.toIterable(generator)) {
n++; n++;
int rand = (int) (Math.random() * n); int rand = (int) (Math.random() * n);
// At this point, 0 <= rand < n. // At this point, 0 <= rand < n.
rand++; // Now, 1 <= rand <= n. rand++; // Now, 1 <= rand <= n.
if (rand == 1) { if (rand == 1) {
// We rolled a 1 on an n-sided die. We have a new candidate! // We rolled a 1 on an n-sided die. We have a new candidate!
// Note that on the first iteration, this always happens, // Note that on the first iteration, this always happens,
// because n = 1. // because n = 1.
candidate = item; candidate = item;
} }
} }
if (n == 0) { if (n == 0) {
// There were no items in the generator! // There were no items in the generator!
throw new NoSuchElementException("generator is empty"); throw new NoSuchElementException("generator is empty");
} }
return candidate; return candidate;
} }
} }