General FizzBuzz/jFizzBuzz

From Rosetta Code
Works with: Java version 1.8.x

User-supplied values must be passed as command-line arguments.

/**
*
* FizzBuzz Enterprise Edition (c) 2016
*
*
* TODO: Add End-User License Agreement
* TODO: Add JavaDoc Comments
* TODO: Add Unit Tests
* TODO: Add Dependency Injection (FizzBuzzProvider, BuzzerProvider, etc.)
*
*
*/

 
package com.fizzbuzzinc.jfizzbuzz;
 
 
import java.util.List;
import java.util.ArrayList;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.Iterator;
 
 
class BuzzException extends Exception
{
public BuzzException(
String textualRepresentation
)
{
super(textualRepresentation);
}
}
 
 
interface IBuzzer
{
void buzz(
Integer numericValue
)
throws BuzzException;
}
 
 
interface IFizzBuzz
{
Boolean addBuzzer(
IBuzzer buzzerToAddToTheListOfBuzzers
);
 
String doExecute();
}
 
 
class Buzzer implements IBuzzer
{
protected final Integer numericValue;
protected final String textualRepresentation;
 
public Buzzer(
Integer numericValue,
String textualRepresentation
)
{
this.numericValue = numericValue;
this.textualRepresentation = textualRepresentation;
}
 
public void buzz(
Integer numericValue
)
throws BuzzException
{
Integer moduloOfNumericValues = new Integer(numericValue % this.getNumericValue());
 
if (moduloOfNumericValues.equals(new Integer(0)))
{
throw new BuzzException(this.getTextualRepresentation());
}
 
}
 
Integer getNumericValue()
{
return this.numericValue;
}
 
String getTextualRepresentation()
{
return this.textualRepresentation;
}
}
 
 
/**
*
* Thread-safe implementation of {@link IFizzBuzz}.
*
*/

class FizzBuzz implements IFizzBuzz
{
protected final Integer numericvalueOfUpperLimit;
protected final List<IBuzzer> listOfBuzzers;
 
public FizzBuzz(
Integer numericvalueOfUpperLimit
)
{
this.numericvalueOfUpperLimit = numericvalueOfUpperLimit;
this.listOfBuzzers = new ArrayList<IBuzzer>();
}
 
public synchronized Boolean addBuzzer(
IBuzzer buzzerToAddToTheListOfBuzzers
)
{
return new Boolean(this.listOfBuzzers.add(buzzerToAddToTheListOfBuzzers));
}
 
public synchronized String doExecute()
{
StringBuilder textualRepresentationOfFizzBuzzProgramOutput = new StringBuilder();
 
for (
Integer loopIndex = new Integer(1);
loopIndex <= this.numericvalueOfUpperLimit;
loopIndex += new Integer(1)
)
{
Boolean atLeastOneBuzzerBuzzed = new Boolean(false);
 
for (
Integer buzzerIndex = new Integer(0);
buzzerIndex < new Integer(this.listOfBuzzers.size());
buzzerIndex += new Integer(1)
)
{
IBuzzer buzzer = this.listOfBuzzers.get(buzzerIndex);
try
{
buzzer.buzz(loopIndex);
}
catch (BuzzException buzzException)
{
textualRepresentationOfFizzBuzzProgramOutput.append(buzzException.getMessage());
atLeastOneBuzzerBuzzed = new Boolean(true);
}
}
 
if (atLeastOneBuzzerBuzzed.equals(new Boolean(false)))
{
textualRepresentationOfFizzBuzzProgramOutput.append(loopIndex.toString());
}
 
textualRepresentationOfFizzBuzzProgramOutput.append(new String("\n"));
}
 
return textualRepresentationOfFizzBuzzProgramOutput.toString();
 
}
 
}
 
 
class FizzBuzzEnterpriseDemo
{
public static void main(
String[] programArgumentsAsProvidedByTheEndUser
)
{
final UserSuppliedArguments userSuppliedArguments;
 
try
{
userSuppliedArguments = new UserSuppliedArguments(programArgumentsAsProvidedByTheEndUser);
}
catch (IllegalArgumentException illegalArgumentException)
{
System.err.println(illegalArgumentException.getMessage());
System.exit(1);
return;
}
 
final FizzBuzz fizzBuzz = new FizzBuzz(userSuppliedArguments.numericValueOfUpperLimit);
 
Iterator buzzerEntriesIterator = userSuppliedArguments.buzzerEntries.entrySet().iterator();
 
while (buzzerEntriesIterator.hasNext())
{
Map.Entry numericValueTextualRepresentationPair = (Map.Entry) buzzerEntriesIterator.next();
 
fizzBuzz.addBuzzer(new Buzzer(
(Integer) numericValueTextualRepresentationPair.getKey(),
(String) numericValueTextualRepresentationPair.getValue()
));
}
 
System.out.println(fizzBuzz.doExecute());
 
}
 
 
private static class UserSuppliedArguments
{
public final Integer numericValueOfUpperLimit;
public final Map<Integer,String> buzzerEntries;
 
private UserSuppliedArguments(
String[] sourceArguments
)
throws IllegalArgumentException
{
Integer requiredAmountOfUserSuppliedArguments = new Integer(7);
Integer actualAmountOfUserSuppliedArguments = new Integer(sourceArguments.length);
 
if (actualAmountOfUserSuppliedArguments < requiredAmountOfUserSuppliedArguments)
{
throw new IllegalArgumentException(String.format(
"End user did not provide sufficient amount of command-line program arguments.\n"+
"Required amount of arguments: %d\n"+
"Amount of arguments supplied by the end used: %d\n",
requiredAmountOfUserSuppliedArguments, actualAmountOfUserSuppliedArguments
));
}
 
this.buzzerEntries = new LinkedHashMap<Integer,String>();
 
 
String textualValueOfUpperLimit = sourceArguments[new Integer(0)];
Integer numericValueOfUpperLimit;
 
try
{
numericValueOfUpperLimit = new Integer(textualValueOfUpperLimit);
if (numericValueOfUpperLimit < new Integer(0))
{
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException illegalArgumentException)
{
throw new IllegalArgumentException(String.format(
"End user supplied invalid value for upper limit for the FizzBuzz execution.\n"+
"Required non-negative integer value.\n"+
"Value supplied by the end user: %s\n",
textualValueOfUpperLimit
));
}
 
this.numericValueOfUpperLimit = numericValueOfUpperLimit;
 
 
for (
Integer loopIndex = new Integer(1);
loopIndex <= new Integer(3);
loopIndex += new Integer(1)
)
{
Integer numericValueArgumentIndex = loopIndex * new Integer(2) - new Integer(1);
Integer textualRepresentationArgumentIndex = numericValueArgumentIndex + new Integer(1);
 
Integer buzzerNumericValue;
String buzzerTextualValue;
String buzzerTextualRepresentation;
 
buzzerTextualRepresentation = sourceArguments[textualRepresentationArgumentIndex];
buzzerTextualValue = sourceArguments[numericValueArgumentIndex];
 
try
{
buzzerNumericValue = new Integer(buzzerTextualValue);
if (buzzerNumericValue <= new Integer(0))
{
throw new IllegalArgumentException();
}
}
catch (IllegalArgumentException illegalArgumentException)
{
throw new IllegalArgumentException(String.format(
"End user supplied invalid numeric value for buzzer %d.\n"+
"Required positive integer value.\n"+
"Value supplied by the end user: %s\n",
loopIndex, buzzerTextualValue
));
}
 
this.buzzerEntries.put(buzzerNumericValue, buzzerTextualRepresentation);
}
 
}
 
}
 
}