001: /*
002: * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS HEADER.
003: *
004: * Copyright 1997-2007 Sun Microsystems, Inc. All rights reserved.
005: *
006: * The contents of this file are subject to the terms of either the GNU
007: * General Public License Version 2 only ("GPL") or the Common
008: * Development and Distribution License("CDDL") (collectively, the
009: * "License"). You may not use this file except in compliance with the
010: * License. You can obtain a copy of the License at
011: * http://www.netbeans.org/cddl-gplv2.html
012: * or nbbuild/licenses/CDDL-GPL-2-CP. See the License for the
013: * specific language governing permissions and limitations under the
014: * License. When distributing the software, include this License Header
015: * Notice in each file and include the License file at
016: * nbbuild/licenses/CDDL-GPL-2-CP. Sun designates this
017: * particular file as subject to the "Classpath" exception as provided
018: * by Sun in the GPL Version 2 section of the License file that
019: * accompanied this code. If applicable, add the following below the
020: * License Header, with the fields enclosed by brackets [] replaced by
021: * your own identifying information:
022: * "Portions Copyrighted [year] [name of copyright owner]"
023: *
024: * Contributor(s):
025: *
026: * The Original Software is NetBeans. The Initial Developer of the Original
027: * Software is Sun Microsystems, Inc. Portions Copyright 1997-2006 Sun
028: * Microsystems, Inc. All Rights Reserved.
029: *
030: * If you wish your version of this file to be governed by only the CDDL
031: * or only the GPL Version 2, indicate your decision by adding
032: * "[Contributor] elects to include this software in this distribution
033: * under the [CDDL or GPL Version 2] license." If you do not indicate a
034: * single choice of license, a recipient has the option to distribute
035: * your version of this file under either the CDDL, the GPL Version 2 or
036: * to extend the choice of license to its licensees as provided above.
037: * However, if you add GPL Version 2 code and therefore, elected the GPL
038: * Version 2 license, then the option applies only if the new code is
039: * made subject to such option by the copyright holder.
040: */
041: package org.openide;
042:
043: import java.lang.reflect.InvocationTargetException;
044: import org.netbeans.junit.NbTestSuite;
045:
046: import java.awt.Component;
047: import java.util.*;
048: import javax.swing.*;
049: import javax.swing.JLabel;
050: import javax.swing.event.ChangeListener;
051: import org.netbeans.junit.NbTestCase;
052: import org.openide.util.*;
053: import org.openide.util.HelpCtx;
054:
055: /** Test coveres implementation of issue 58530 - Background wizard validation.
056: * @author Jiri Rechtacek
057: */
058: public class AsynchronousValidatingPanelTest extends LoggingTestCaseHid {
059:
060: public AsynchronousValidatingPanelTest(String name) {
061: super (name);
062: }
063:
064: public static void main(String[] args) {
065: junit.textui.TestRunner.run(new NbTestSuite(
066: AsynchronousValidatingPanelTest.class));
067: System.exit(0);
068: }
069:
070: WizardDescriptor wd;
071: String exceptedValue;
072:
073: private ErrorManager err;
074:
075: protected final void setUp() {
076: WizardDescriptor.Panel panels[] = new WizardDescriptor.Panel[2];
077: panels[0] = new Panel("first panel");
078: panels[1] = new Panel("second panel");
079: wd = new WizardDescriptor(panels);
080: wd.addPropertyChangeListener(new Listener());
081: java.awt.Dialog d = DialogDisplayer.getDefault().createDialog(
082: wd);
083: //d.show();
084: err = ErrorManager.getDefault()
085: .getInstance("test-" + getName());
086: }
087:
088: public void testAsynchronousLazyValidation() throws Exception {
089: Panel panels[] = new Panel[3];
090:
091: class MyPanel extends Panel implements
092: WizardDescriptor.AsynchronousValidatingPanel {
093: public String validateMsg;
094: public String failedMsg;
095: public boolean running;
096: public boolean wasEnabled;
097:
098: public MyPanel() {
099: super ("enhanced panel");
100: }
101:
102: public void prepareValidation() {
103: running = true;
104: }
105:
106: public synchronized void validate()
107: throws WizardValidationException {
108: err.log("validate() entry.");
109: wasEnabled = wd.isNextEnabled() || wd.isFinishEnabled();
110: running = false;
111: notifyAll();
112: if (validateMsg != null) {
113: failedMsg = validateMsg;
114: err.log("Throw WizardValidationException.");
115: throw new WizardValidationException(null,
116: "MyPanel.validate() failed.", validateMsg);
117: }
118: err.log("validate() exit.");
119: return;
120: }
121: }
122:
123: class MyFinishPanel extends MyPanel implements
124: WizardDescriptor.FinishablePanel {
125: public boolean isFinishPanel() {
126: return true;
127: }
128: }
129:
130: MyPanel mp = new MyPanel();
131: MyFinishPanel mfp = new MyFinishPanel();
132: panels[0] = mp;
133: panels[1] = mfp;
134: panels[2] = new Panel("Last one");
135: wd = new WizardDescriptor(panels);
136:
137: assertNull("Component has not been yet initialized",
138: panels[1].component);
139: mp.failedMsg = null;
140: mp.validateMsg = "xtest-fail-without-msg";
141: assertTrue("Next button must be enabled.", wd.isNextEnabled());
142: err.log("Do Next. Validation will run with: validateMsg="
143: + mp.validateMsg + ", failedMsg=" + mp.failedMsg);
144: synchronized (mp) {
145: wd.doNextClick();
146: assertTrue("Validation runs.", mp.running);
147: assertFalse("Wizard is not valid when validation runs.", wd
148: .isForwardEnabled());
149: // let's wait till wizard is valid
150: while (mp.running) {
151: assertFalse("Wizard is not valid during validation.",
152: wd.isForwardEnabled());
153: mp.wait();
154: }
155: }
156: waitWhileSetValidDone();
157: assertFalse("Finish is disabled during validation.",
158: mp.wasEnabled);
159: assertTrue(
160: "Wizard is ready to next validation however previous failed.",
161: wd.isForwardEnabled());
162: assertEquals("The lazy validation failed on Next.",
163: mp.validateMsg, mp.failedMsg);
164: assertNull(
165: "The lazy validation failed, still no initialiaation",
166: panels[1].component);
167: assertNull(
168: "The lazy validation failed, still no initialiaation",
169: panels[2].component);
170: mp.failedMsg = null;
171: mp.validateMsg = null;
172: synchronized (mp) {
173: err.log("Do Next. Validation will run with: validateMsg="
174: + mp.validateMsg + ", failedMsg=" + mp.failedMsg);
175: assertTrue("Wizard is valid before validation.", wd
176: .isForwardEnabled());
177: wd.doNextClick();
178: assertTrue("Validation runs.", mp.running);
179: while (mp.running) {
180: assertFalse("Wizard is not valid during validation.",
181: wd.isForwardEnabled());
182: mp.wait();
183: }
184: }
185: waitWhileSetValidDone();
186: assertFalse("Finish is disabled during validation.",
187: mp.wasEnabled);
188: assertTrue("Wizard is valid when validation passes.", wd
189: .isForwardEnabled());
190: assertNull("Validation on Next passes", mp.failedMsg);
191: assertNotNull("Now we switched to another panel",
192: panels[1].component);
193: assertNull(
194: "The lazy validation failed, still no initialiaation",
195: panels[2].component);
196:
197: // remember previous state
198: Object state = wd.getValue();
199: mfp.validateMsg = "xtest-fail-without-msg";
200: mfp.failedMsg = null;
201: synchronized (mfp) {
202: err.log("Do Finish. Validation will run with: validateMsg="
203: + mfp.validateMsg + ", failedMsg=" + mfp.failedMsg);
204: wd.doFinishClick();
205: while (mfp.running) {
206: assertFalse("Wizard is not valid during validation.",
207: wd.isForwardEnabled());
208: mfp.wait();
209: }
210: }
211: waitWhileSetValidDone();
212: assertFalse("Finish is disabled during validation.",
213: mp.wasEnabled);
214: assertTrue("Wizard is ready to next validation.", wd
215: .isForwardEnabled());
216: assertEquals("The lazy validation failed on Finish.",
217: mfp.validateMsg, mfp.failedMsg);
218: assertNull("The validation failed, still no initialiaation",
219: panels[2].component);
220: assertEquals("State has not changed", state, wd.getValue());
221:
222: mfp.validateMsg = null;
223: mfp.failedMsg = null;
224: synchronized (mfp) {
225: err.log("Do Finish. Validation will run with: validateMsg="
226: + mfp.validateMsg + ", failedMsg=" + mfp.failedMsg);
227: wd.doFinishClick();
228: while (mfp.running) {
229: assertFalse("Wizard is not valid during validation.",
230: wd.isForwardEnabled());
231: mfp.wait();
232: }
233: }
234: waitWhileSetValidDone();
235: assertFalse("Finish is disabled during validation.",
236: mp.wasEnabled);
237: assertTrue("Wizard is valid when validation passes.", wd
238: .isForwardEnabled());
239: assertNull("Validation on Finish passes", mfp.failedMsg);
240: assertNull("Finish was clicked, no initialization either",
241: panels[2].component);
242: assertEquals("The state is finish",
243: WizardDescriptor.FINISH_OPTION, wd.getValue());
244: }
245:
246: public class Panel implements WizardDescriptor.Panel,
247: WizardDescriptor.FinishablePanel {
248: private JLabel component;
249: private String text;
250:
251: public Panel(String text) {
252: this .text = text;
253: }
254:
255: public Component getComponent() {
256: if (component == null) {
257: component = new JLabel(text);
258: }
259: return component;
260: }
261:
262: public void addChangeListener(ChangeListener l) {
263: }
264:
265: public HelpCtx getHelp() {
266: return null;
267: }
268:
269: public boolean isValid() {
270: return true;
271: }
272:
273: public boolean isFinishPanel() {
274: return true;
275: }
276:
277: public void readSettings(Object settings) {
278: log("readSettings of panel: " + text + " [time: "
279: + System.currentTimeMillis()
280: + "] with PROP_VALUE: "
281: + handleValue(wd.getValue()));
282: }
283:
284: public void removeChangeListener(ChangeListener l) {
285: }
286:
287: public void storeSettings(Object settings) {
288: log("storeSettings of panel: " + text + " [time: "
289: + System.currentTimeMillis()
290: + "] with PROP_VALUE: "
291: + handleValue(wd.getValue()));
292: if (exceptedValue != null) {
293: assertEquals("WD.getValue() returns excepted value.",
294: exceptedValue, handleValue(wd.getValue()));
295: }
296: }
297:
298: }
299:
300: public class Listener implements java.beans.PropertyChangeListener {
301:
302: public void propertyChange(
303: java.beans.PropertyChangeEvent propertyChangeEvent) {
304: if (WizardDescriptor.PROP_VALUE.equals(propertyChangeEvent
305: .getPropertyName())) {
306: log("propertyChange [time: "
307: + System.currentTimeMillis()
308: + "] with PROP_VALUE: "
309: + handleValue(wd.getValue()));
310:
311: }
312: }
313:
314: }
315:
316: public String handleValue(Object val) {
317: if (val == null)
318: return "NULL";
319: if (val instanceof String)
320: return (String) val;
321: if (WizardDescriptor.FINISH_OPTION.equals(val))
322: return "FINISH_OPTION";
323: if (WizardDescriptor.CANCEL_OPTION.equals(val))
324: return "CANCEL_OPTION";
325: if (WizardDescriptor.CLOSED_OPTION.equals(val))
326: return "CLOSED_OPTION";
327: if (val instanceof JButton) {
328: JButton butt = (JButton) val;
329: ResourceBundle b = NbBundle.getBundle("org.openide.Bundle"); // NOI18N
330: if (b.getString("CTL_NEXT").equals(butt.getText()))
331: return "NEXT_OPTION";
332: if (b.getString("CTL_PREVIOUS").equals(butt.getText()))
333: return "NEXT_PREVIOUS";
334: if (b.getString("CTL_FINISH").equals(butt.getText()))
335: return "FINISH_OPTION";
336: if (b.getString("CTL_CANCEL").equals(butt.getText()))
337: return "CANCEL_OPTION";
338: }
339: return "UNKNOWN OPTION: " + val;
340: }
341:
342: private void waitWhileSetValidDone() {
343: err.log("Start waitWhileSetValidDone.");
344: try {
345: WizardDescriptor.ASYNCHRONOUS_JOBS_RP.post(new Runnable() {
346: public void run() {
347: }
348: }).waitFinished();
349: SwingUtilities.invokeAndWait(new Runnable() {
350: public void run() {
351: }
352: });
353: } catch (InterruptedException ex) {
354: fail(ex.getMessage());
355: } catch (InvocationTargetException ex) {
356: fail(ex.getMessage());
357: }
358: err.log("End of waitWhileSetValidDone.");
359: }
360:
361: }
|