001: /* Copyright 2001 The JA-SIG Collaborative. All rights reserved.
002: * See license distributed with this file and
003: * available online at http://www.uportal.org/license.html
004: */
005:
006: package org.jasig.portal.channels;
007:
008: import java.io.StringWriter;
009: import java.util.ResourceBundle;
010: import java.text.MessageFormat;
011: import java.lang.String;
012:
013: import org.jasig.portal.ChannelRuntimeData;
014: import org.jasig.portal.ChannelRuntimeProperties;
015: import org.jasig.portal.ChannelStaticData;
016: import org.jasig.portal.IChannel;
017: import org.jasig.portal.PortalEvent;
018: import org.jasig.portal.PortalException;
019: import org.apache.commons.logging.Log;
020: import org.apache.commons.logging.LogFactory;
021: import org.jasig.portal.utils.XSLT;
022: import org.xml.sax.ContentHandler;
023:
024: /** <p>A number guessing game which asks the user to enter a number within
025: * a certain range as determined by this channel's parameters.</p>
026: * @author Ken Weiner, kweiner@unicon.net
027: * @version $Revision: 35982 $
028: */
029: public class CNumberGuess implements IChannel {
030: private static final Log log = LogFactory
031: .getLog(CNumberGuess.class);
032: ChannelStaticData staticData = null;
033: ChannelRuntimeData runtimeData = null;
034:
035: private static final String sslLocation = "CNumberGuess/CNumberGuess.ssl";
036: private static final String bundleLocation = "/org/jasig/portal/channels/CNumberGuess/CNumberGuess";
037: private int iMinNum = 0;
038: private int iMaxNum = 0;
039: private int iGuess = 0;
040: private int iGuesses = 0;
041: private int iAnswer = 0;
042: private boolean bFirstTime = true;
043:
044: /** Constructs a CNumberGuess.
045: */
046: public CNumberGuess() {
047: this .staticData = new ChannelStaticData();
048: this .runtimeData = new ChannelRuntimeData();
049: }
050:
051: /** Returns channel runtime properties
052: * @return handle to runtime properties
053: */
054: public ChannelRuntimeProperties getRuntimeProperties() {
055: // Channel will always render, so the default values are ok
056: return new ChannelRuntimeProperties();
057: }
058:
059: /** Processes layout-level events coming from the portal
060: * @param ev a portal layout event
061: */
062: public void receiveEvent(PortalEvent ev) {
063: // no events for this channel
064: }
065:
066: /** Receive static channel data from the portal
067: * @param sd static channel data
068: */
069: public void setStaticData(ChannelStaticData sd) {
070: this .staticData = sd;
071:
072: String sMinNum = null;
073: String sMaxNum = null;
074:
075: try {
076: if ((sMinNum = sd.getParameter("minNum")) != null)
077: iMinNum = Integer.parseInt(sMinNum);
078:
079: if ((sMaxNum = sd.getParameter("maxNum")) != null)
080: iMaxNum = Integer.parseInt(sMaxNum);
081:
082: iAnswer = getRandomNumber(iMinNum, iMaxNum);
083: } catch (NumberFormatException nfe) {
084: iMinNum = 0;
085: iMaxNum = 100;
086:
087: if (log.isWarnEnabled())
088: log
089: .warn("CNumberGuess::setStaticData() : either "
090: + sMinNum
091: + " or "
092: + sMaxNum
093: + " (minNum, maxNum) is not a valid integer. Defaults "
094: + iMinNum + " and " + iMaxNum
095: + " will be used instead.");
096: }
097: }
098:
099: /** Receives channel runtime data from the portal and processes actions
100: * passed to it. The names of these parameters are entirely up to the channel.
101: * @param rd handle to channel runtime data
102: */
103: public void setRuntimeData(ChannelRuntimeData rd) {
104: this .runtimeData = rd;
105:
106: String sGuess = runtimeData.getParameter("guess");
107:
108: if (sGuess != null) {
109: try {
110: iGuess = Integer.parseInt(sGuess);
111: } catch (NumberFormatException nfe) {
112: // Assume that the guess was the same as last time
113: }
114:
115: bFirstTime = false;
116: iGuesses++;
117: }
118: }
119:
120: /** Output channel content to the portal
121: * @param out a sax document handler
122: */
123: public void renderXML(ContentHandler out) throws PortalException {
124: String sSuggest = null;
125:
126: ResourceBundle l10n = ResourceBundle.getBundle(bundleLocation,
127: runtimeData.getLocales()[0]);
128:
129: if (iGuess < iAnswer)
130: sSuggest = l10n.getString("HIGHER");
131: else if (iGuess > iAnswer)
132: sSuggest = l10n.getString("LOWER");
133:
134: String GUESS_SUGGEST = MessageFormat.format(l10n
135: .getString("GUESS_SUGGEST"), new Object[] { sSuggest });
136: String THE_ANSWER_WAS_X = MessageFormat.format(l10n
137: .getString("THE_ANSWER_WAS_X"), new Object[] { String
138: .valueOf(iAnswer) });
139: String YOU_GOT_IT_AFTER_X_TRIES = MessageFormat.format(l10n
140: .getString("YOU_GOT_IT_AFTER_X_TRIES"),
141: new Object[] { String.valueOf(iGuesses) });
142: String YOU_HAVE_MADE_X_GUESSES = MessageFormat.format(l10n
143: .getString("YOU_HAVE_MADE_X_GUESSES"),
144: new Object[] { String.valueOf(iGuesses) });
145: String YOUR_GUESS_OF_GUESS_WAS_INCORRECT = MessageFormat
146: .format(
147: l10n
148: .getString("YOUR_GUESS_OF_GUESS_WAS_INCORRECT"),
149: new Object[] { String.valueOf(iGuess) });
150: String I_AM_THINKING_OF_A_NUMBER_BETWEEN_X_AND_Y = MessageFormat
151: .format(
152: l10n
153: .getString("I_AM_THINKING_OF_A_NUMBER_BETWEEN_X_AND_Y"),
154: new Object[] { String.valueOf(iMinNum),
155: String.valueOf(iMaxNum) });
156:
157: StringWriter w = new StringWriter();
158: w.write("<?xml version='1.0'?>\n");
159: w.write("<content>\n");
160: w.write(" <minNum>" + iMinNum + "</minNum>\n");
161: w.write(" <maxNum>" + iMaxNum + "</maxNum>\n");
162: w.write(" <guesses>" + iGuesses + "</guesses>\n");
163: w.write(" <guess>" + iGuess + "</guess>\n");
164:
165: if (bFirstTime)
166: ; // Do nothing
167: else if (iGuess == iAnswer) {
168: w.write(" <answer>" + iAnswer + "</answer>\n");
169: bFirstTime = true;
170: iGuesses = 0;
171: iAnswer = getRandomNumber(iMinNum, iMaxNum);
172: } else
173: w.write(" <suggest>" + sSuggest + "</suggest>\n");
174:
175: w.write("</content>\n");
176:
177: XSLT xslt = XSLT.getTransformer(this );
178: xslt.setResourceBundle(l10n);
179: xslt.setXML(w.toString());
180: xslt.setXSL(sslLocation, "main", runtimeData.getBrowserInfo());
181: xslt.setTarget(out);
182: xslt.setStylesheetParameter("baseActionURL", runtimeData
183: .getBaseActionURL());
184: xslt.setStylesheetParameter("guessSuggest", GUESS_SUGGEST);
185: xslt.setStylesheetParameter("theAnswerWasX", THE_ANSWER_WAS_X);
186: xslt.setStylesheetParameter("youHaveMadeXGuesses",
187: YOU_HAVE_MADE_X_GUESSES);
188: xslt.setStylesheetParameter("youGotItAfterXTries",
189: YOU_GOT_IT_AFTER_X_TRIES);
190: xslt.setStylesheetParameter("YourGuessOfGuessWasIncorrect",
191: YOUR_GUESS_OF_GUESS_WAS_INCORRECT);
192: xslt.setStylesheetParameter("IAmThinkingOfANumberBetweenXAndY",
193: I_AM_THINKING_OF_A_NUMBER_BETWEEN_X_AND_Y);
194: xslt.transform();
195: }
196:
197: private int getRandomNumber(int min, int max) {
198: return new Double((max - min) * Math.random() + min).intValue();
199: }
200: }
|