001: /*
002: * This file is part of the Echo Web Application Framework (hereinafter "Echo").
003: * Copyright (C) 2002-2005 NextApp, Inc.
004: *
005: * Version: MPL 1.1/GPL 2.0/LGPL 2.1
006: *
007: * The contents of this file are subject to the Mozilla Public License Version
008: * 1.1 (the "License"); you may not use this file except in compliance with
009: * the License. You may obtain a copy of the License at
010: * http://www.mozilla.org/MPL/
011: *
012: * Software distributed under the License is distributed on an "AS IS" basis,
013: * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
014: * for the specific language governing rights and limitations under the
015: * License.
016: *
017: * Alternatively, the contents of this file may be used under the terms of
018: * either the GNU General Public License Version 2 or later (the "GPL"), or
019: * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
020: * in which case the provisions of the GPL or the LGPL are applicable instead
021: * of those above. If you wish to allow use of your version of this file only
022: * under the terms of either the GPL or the LGPL, and not to allow others to
023: * use your version of this file under the terms of the MPL, indicate your
024: * decision by deleting the provisions above and replace them with the notice
025: * and other provisions required by the GPL or the LGPL. If you do not delete
026: * the provisions above, a recipient may use your version of this file under
027: * the terms of any one of the MPL, the GPL or the LGPL.
028: */
029:
030: package nextapp.echo2.testapp.interactive;
031:
032: import nextapp.echo2.app.ApplicationInstance;
033: import nextapp.echo2.app.TaskQueueHandle;
034: import nextapp.echo2.app.Window;
035: import nextapp.echo2.webcontainer.ContainerContext;
036: import nextapp.echo2.webrender.ClientConfiguration;
037:
038: /**
039: * Interactive Test Application Instance.
040: * <p>
041: * <b>WARNING TO DEVELOPERS:</b>
042: * <p>
043: * Beware that the Interactive Test Application is not a good example of an
044: * Echo application. The intent of this application is to serve as a running
045: * testbed for the Echo framework. As such, the requirements of this
046: * application are dramatically different from a production internet
047: * application. There is stuff in this code of this application that is
048: * downright absurd. Please do not look to this application to see good design
049: * practices for building your own Echo applications--you will not find them
050: * here.
051: */
052: public class InteractiveApp extends ApplicationInstance {
053:
054: private static final String[] GHOST_SCRIPT_1 = new String[] {
055: "EnterTestApplication", "StartTest:ButtonTest",
056: "StartTest:SplitPaneNestedTest", "StartTest:ListBoxTest",
057: "StartTest:TextComponentTest", "StartTest:StyleSheetTest",
058: "StartTest:ContainerContextTest", "StartTest:GridTest",
059: "StartTest:HierarchyTest", "ExitTestApplication" };
060:
061: /**
062: * A boolean flag indicating whether the application is running on a live
063: * demo server. This flag is used to disable certain tests based on
064: * whether the <code>nextapp.echo2.demoserver</code> system property is
065: * set.
066: */
067: public static final boolean LIVE_DEMO_SERVER;
068: static {
069: boolean liveDemoServer;
070: try {
071: if ("true".equals(System.getProperties().getProperty(
072: "nextapp.echo2.demoserver"))) {
073: liveDemoServer = true;
074: } else {
075: liveDemoServer = false;
076: }
077: } catch (SecurityException ex) {
078: liveDemoServer = false;
079: }
080: LIVE_DEMO_SERVER = liveDemoServer;
081: }
082:
083: /**
084: * Convenience method to return the <code>ThreadLocal</code> instance
085: * precast to the appropriate type.
086: *
087: * @return the active <code>InteractiveApp</code>
088: * @see #getActive()
089: */
090: public static InteractiveApp getApp() {
091: return (InteractiveApp) ApplicationInstance.getActive();
092: }
093:
094: private TaskQueueHandle ghostTaskQueue;
095: private Window mainWindow;
096: private ConsoleWindowPane console;
097:
098: /**
099: * Writes a message to a pop-up debugging console.
100: * The console is used for displaying information such as
101: * fired events.
102: *
103: * @param message the message to write to the console
104: */
105: public void consoleWrite(String message) {
106: if (console == null) {
107: console = new ConsoleWindowPane();
108: getDefaultWindow().getContent().add(console);
109: } else if (console.getParent() == null) {
110: getDefaultWindow().getContent().add(console);
111: }
112: console.writeMessage(message);
113: }
114:
115: /**
116: * Displays a <code>TestPane</code> from which the user may select an
117: * interactive test to run.
118: */
119: public void displayTestPane() {
120: mainWindow.setContent(new TestPane());
121: }
122:
123: /**
124: * Displays the <code>WelcomePane</code> which greets new users visiting
125: * the application.
126: */
127: public void displayWelcomePane() {
128: mainWindow.setContent(new WelcomePane());
129: }
130:
131: private String getRequestParameter(String parameterName) {
132: ContainerContext cc = (ContainerContext) getContextProperty(ContainerContext.CONTEXT_PROPERTY_NAME);
133: Object parameterValue = cc.getInitialRequestParameterMap().get(
134: parameterName);
135: if (parameterValue instanceof String) {
136: return (String) parameterValue;
137: } else if (parameterValue instanceof String[]) {
138: return ((String[]) parameterValue).length == 0 ? null
139: : ((String[]) parameterValue)[0];
140: } else {
141: return parameterValue == null ? null : parameterValue
142: .toString();
143: }
144: }
145:
146: /**
147: * @see nextapp.echo2.app.ApplicationInstance#init()
148: */
149: public Window init() {
150: setStyleSheet(Styles.DEFAULT_STYLE_SHEET);
151: mainWindow = new Window();
152: mainWindow.setTitle("NextApp Echo2 Test Application");
153: mainWindow.setContent(new WelcomePane());
154:
155: ContainerContext cc = (ContainerContext) getContextProperty(ContainerContext.CONTEXT_PROPERTY_NAME);
156: if (!LIVE_DEMO_SERVER) {
157: if (cc.getInitialRequestParameterMap().containsKey("ghost")) {
158: GhostTask ghostTask = new GhostTask();
159:
160: if ("1".equals(getRequestParameter("script"))) {
161: ghostTask.setScript(GHOST_SCRIPT_1);
162: }
163: if (cc.getInitialRequestParameterMap().containsKey(
164: "clicks")) {
165: ghostTask.setClicksPerIteration(Integer
166: .parseInt(getRequestParameter("clicks")));
167: }
168: if (cc.getInitialRequestParameterMap().containsKey(
169: "iterations")) {
170: ghostTask
171: .setTotalIterations(Integer
172: .parseInt(getRequestParameter("iterations")));
173: }
174: startGhostTask(ghostTask, 0);
175: }
176: }
177:
178: ClientConfiguration clientConfiguration = new ClientConfiguration();
179: clientConfiguration.setProperty(
180: ClientConfiguration.PROPERTY_SERVER_ERROR_MESSAGE,
181: "KA-BOOM! (test non-default server error message)");
182: cc.setClientConfiguration(clientConfiguration);
183:
184: return mainWindow;
185: }
186:
187: /**
188: * Sets the window title to display the current iteration of the ghost
189: * test.
190: *
191: * @param iteration the iteration number (negative values will restore
192: * the window title to its normal state)
193: */
194: public void setGhostIterationWindowTitle(int iteration) {
195: if (iteration < 0) {
196: mainWindow.setTitle("NextApp Echo2 Test Application");
197: } else {
198: mainWindow.setTitle("Iteration #" + iteration);
199: }
200: }
201:
202: /**
203: * Starts the ghost test with the specified callback interval, run-time,
204: * and clicks-per-iteration.
205: *
206: * @param interval the callback interval between ghost actions, in
207: * milliseconds
208: */
209: public void startGhostTask(GhostTask ghostTask, int interval) {
210: if (ghostTaskQueue != null) {
211: return;
212: }
213: ghostTaskQueue = createTaskQueue();
214: ContainerContext containerContext = (ContainerContext) getContextProperty(ContainerContext.CONTEXT_PROPERTY_NAME);
215: containerContext.setTaskQueueCallbackInterval(ghostTaskQueue,
216: interval);
217: ghostTask.startTask(this , ghostTaskQueue);
218: }
219:
220: /**
221: * Stops the currently running ghost test.
222: */
223: public void stopGhostTest() {
224: removeTaskQueue(ghostTaskQueue);
225: ghostTaskQueue = null;
226: }
227: }
|