The four source files for the guessnumber example are
The @MaxNumber qualifier interface
The @Random qualifier interface
The Generator managed bean, which defines producer methods
The UserNumberBean managed bean
The source files are located in the following directory:
tut-install/examples/cdi/guessnumber/src/java/guessnumber
The @MaxNumber qualifier interface is defined as follows:
package guessnumber; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented @Qualifier public @interface MaxNumber { }
The @Random qualifier interface is defined as follows:
package guessnumber; import static java.lang.annotation.ElementType.FIELD; import static java.lang.annotation.ElementType.METHOD; import static java.lang.annotation.ElementType.PARAMETER; import static java.lang.annotation.ElementType.TYPE; import static java.lang.annotation.RetentionPolicy.RUNTIME; import java.lang.annotation.Documented; import java.lang.annotation.Retention; import java.lang.annotation.Target; import javax.inject.Qualifier; @Target( { TYPE, METHOD, PARAMETER, FIELD }) @Retention(RUNTIME) @Documented @Qualifier public @interface Random { }
The Generator managed bean contains the two producer methods for the application. The bean has the @ApplicationScoped annotation to specify that its context extends for the duration of the user’s interaction with the application:
package guessnumber; import java.io.Serializable; import javax.enterprise.context.ApplicationScoped; import javax.enterprise.inject.Produces; @ApplicationScoped public class Generator implements Serializable { private static final long serialVersionUID = -7213673465118041882L; private java.util.Random random = new java.util.Random( System.currentTimeMillis() ); private int maxNumber = 100; java.util.Random getRandom() { return random; } @Produces @Random int next() { return getRandom().nextInt(maxNumber); } @Produces @MaxNumber int getMaxNumber() { return maxNumber; } }
The UserNumberBean managed bean, the backing bean for the JavaServer Faces application, provides the basic logic for the game. This bean does the following:
Implements setter and getter methods for the bean fields
Injects the two qualifier objects
Provides a reset method that allows you to begin a new game after you complete one
Provides a check method that determines whether the user has guessed the number
Provides a validateNumberRange method that determines whether the user’s input is correct
The bean is defined as follows:
package guessnumber; import java.io.Serializable; import javax.annotation.PostConstruct; import javax.enterprise.context.SessionScoped; import javax.enterprise.inject.Instance; import javax.inject.Inject; import javax.inject.Named; import javax.faces.application.FacesMessage; import javax.faces.component.UIComponent; import javax.faces.component.UIInput; import javax.faces.context.FacesContext; @Named @SessionScoped public class UserNumberBean implements Serializable { private static final long serialVersionUID = 1L; private int number; private Integer userNumber; private int minimum; private int remainingGuesses; @MaxNumber @Inject private int maxNumber; private int maximum; @Random @Inject Instance<Integer> randomInt; public UserNumberBean() { } public int getNumber() { return number; } public void setUserNumber(Integer user_number) { userNumber = user_number; } public Integer getUserNumber() { return userNumber; } public int getMaximum() { return (this.maximum); } public void setMaximum(int maximum) { this.maximum = maximum; } public int getMinimum() { return (this.minimum); } public void setMinimum(int minimum) { this.minimum = minimum; } public int getRemainingGuesses() { return remainingGuesses; } public String check() throws InterruptedException { if (userNumber > number) { maximum = userNumber - 1; } if (userNumber < number) { minimum = userNumber + 1; } if (userNumber == number) { FacesContext.getCurrentInstance().addMessage(null, new FacesMessage("Correct!")); } remainingGuesses--; return null; } @PostConstruct public void reset() { this.minimum = 0; this.userNumber = 0; this.remainingGuesses = 10; this.maximum = maxNumber; this.number = randomInt.get(); } public void validateNumberRange(FacesContext context, UIComponent toValidate, Object value) { if (remainingGuesses <= 0) { FacesMessage message = new FacesMessage("No guesses left!"); context.addMessage(toValidate.getClientId(context), message); ((UIInput) toValidate).setValid(false); return; } int input = (Integer) value; if (input < minimum || input > maximum) { ((UIInput) toValidate).setValid(false); FacesMessage message = new FacesMessage("Invalid guess"); context.addMessage(toValidate.getClientId(context), message); } } }