usr/src/java/vpanels/panel/org/opensolaris/os/vp/panel/common/control/Navigator.java
author Stephen Talley <stephen.talley@sun.com>
Fri, 05 Jun 2009 13:06:24 -0400
changeset 304 6630c8b85735
parent 302 ac70675de834
child 323 497a785649eb
permissions -rw-r--r--
9343 Class.getSimpleName is insufficient for most uses
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     1
/*
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     2
 * CDDL HEADER START
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     3
 *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     4
 * The contents of this file are subject to the terms of the
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     5
 * Common Development and Distribution License (the "License").
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     6
 * You may not use this file except in compliance with the License.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     7
 *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     8
 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
     9
 * or http://www.opensolaris.org/os/licensing.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    10
 * See the License for the specific language governing permissions
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    11
 * and limitations under the License.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    12
 *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    13
 * When distributing Covered Code, include this CDDL HEADER in each
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    14
 * file and include the License file at usr/src/OPENSOLARIS.LICENSE.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    15
 * If applicable, add the following below this CDDL HEADER, with the
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    16
 * fields enclosed by brackets "[]" replaced with your own identifying
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    17
 * information: Portions Copyright [yyyy] [name of copyright owner]
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    18
 *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    19
 * CDDL HEADER END
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    20
 */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    21
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    22
/*
219
57841c113efe 6788 package names should share o.o.o.vp prefix
Stephen Talley <stephen.talley@sun.com>
parents: 190
diff changeset
    23
 * Copyright 2009 Sun Microsystems, Inc.  All rights reserved.
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    24
 * Use is subject to license terms.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    25
 */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    26
40
d1412af1ae5b 3215 ActionAbortedException is used too broadly
Stephen Talley <stephen.talley@sun.com>
parents: 30
diff changeset
    27
package org.opensolaris.os.vp.panel.common.control;
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    28
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    29
import java.util.*;
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    30
import java.util.concurrent.*;
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    31
import java.util.regex.Pattern;
219
57841c113efe 6788 package names should share o.o.o.vp prefix
Stephen Talley <stephen.talley@sun.com>
parents: 190
diff changeset
    32
import org.opensolaris.os.vp.util.misc.*;
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    33
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    34
public class Navigator {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    35
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    36
    // Static data
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    37
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    38
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    39
    public static final String PATH_SEPARATOR = "/";
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    40
    public static final String PARENT_ID = "..";
275
1e055a67a9b6 8094 Navigator interface could be simplified
Stephen Talley <stephen.talley@sun.com>
parents: 274
diff changeset
    41
    private static int instanceCounter = 0;
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    42
59
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    43
    //
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    44
    // Instance data
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    45
    //
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    46
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    47
    private Thread dispatchThread;
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    48
    private ThreadPoolExecutor threadPool;
190
555203a2de79 5952 Stack API should conform to java.util.Dequeue specification
Stephen Talley <stephen.talley@sun.com>
parents: 157
diff changeset
    49
    private LinkedList<Control> stack = new LinkedList<Control>();
157
f4316b998c95 4857 all classes that handle event management should use EventListeners class
Stephen Talley <stephen.talley@sun.com>
parents: 156
diff changeset
    50
    private NavigationListeners listeners = new NavigationListeners(false);
156
ad266190d7e6 4537 sysid: closing window during login + confirmation = hang
Stephen Talley <stephen.talley@sun.com>
parents: 139
diff changeset
    51
ad266190d7e6 4537 sysid: closing window during login + confirmation = hang
Stephen Talley <stephen.talley@sun.com>
parents: 139
diff changeset
    52
    //
ad266190d7e6 4537 sysid: closing window during login + confirmation = hang
Stephen Talley <stephen.talley@sun.com>
parents: 139
diff changeset
    53
    // Constructors
ad266190d7e6 4537 sysid: closing window during login + confirmation = hang
Stephen Talley <stephen.talley@sun.com>
parents: 139
diff changeset
    54
    //
ad266190d7e6 4537 sysid: closing window during login + confirmation = hang
Stephen Talley <stephen.talley@sun.com>
parents: 139
diff changeset
    55
275
1e055a67a9b6 8094 Navigator interface could be simplified
Stephen Talley <stephen.talley@sun.com>
parents: 274
diff changeset
    56
    public Navigator() {
304
6630c8b85735 9343 Class.getSimpleName is insufficient for most uses
Stephen Talley <stephen.talley@sun.com>
parents: 302
diff changeset
    57
	String tName = String.format("%s-%d-", TextUtil.getBaseName(getClass()),
275
1e055a67a9b6 8094 Navigator interface could be simplified
Stephen Talley <stephen.talley@sun.com>
parents: 274
diff changeset
    58
	    instanceCounter++);
156
ad266190d7e6 4537 sysid: closing window during login + confirmation = hang
Stephen Talley <stephen.talley@sun.com>
parents: 139
diff changeset
    59
59
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    60
	ThreadFactory factory =
156
ad266190d7e6 4537 sysid: closing window during login + confirmation = hang
Stephen Talley <stephen.talley@sun.com>
parents: 139
diff changeset
    61
	    new NamedThreadFactory(tName) {
59
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    62
		@Override
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    63
		public Thread newThread(Runnable r) {
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    64
		    dispatchThread = super.newThread(r);
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    65
		    return dispatchThread;
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    66
		}
25cc24ff4f57 3329 navigation thread pool should be non-static, per-Navigator
Stephen Talley <stephen.talley@sun.com>
parents: 54
diff changeset
    67
	    };
30
0ad10e34fb31 3025 Thread pools should be named for better diagnostics
Stephen Talley <stephen.talley@sun.com>
parents: 21
diff changeset
    68
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    69
	// Unbounded
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    70
	BlockingQueue<Runnable> queue = new LinkedBlockingQueue<Runnable>();
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    71
157
f4316b998c95 4857 all classes that handle event management should use EventListeners class
Stephen Talley <stephen.talley@sun.com>
parents: 156
diff changeset
    72
	// Use a thread pool with a single core thread to autmatically handle
f4316b998c95 4857 all classes that handle event management should use EventListeners class
Stephen Talley <stephen.talley@sun.com>
parents: 156
diff changeset
    73
	// uncaught exceptions and queued requests
30
0ad10e34fb31 3025 Thread pools should be named for better diagnostics
Stephen Talley <stephen.talley@sun.com>
parents: 21
diff changeset
    74
	threadPool = new ThreadPoolExecutor(
0ad10e34fb31 3025 Thread pools should be named for better diagnostics
Stephen Talley <stephen.talley@sun.com>
parents: 21
diff changeset
    75
	    1, 1, 10, TimeUnit.MINUTES, queue, factory);
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    76
30
0ad10e34fb31 3025 Thread pools should be named for better diagnostics
Stephen Talley <stephen.talley@sun.com>
parents: 21
diff changeset
    77
	threadPool.allowCoreThreadTimeOut(true);
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    78
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    79
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    80
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    81
    // Navigator methods
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    82
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    83
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    84
    /**
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    85
     * Adds a {@link NavigationListener} to be notified when navigation is
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    86
     * stopped and started.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    87
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    88
    public void addNavigationListener(NavigationListener l) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    89
	listeners.add(l);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    90
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    91
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
    92
    /**
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
    93
     * Runs the given {@code Runnable} asynchronously on this {@code
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
    94
     * Navigator}'s navigation thread.	This thread is intended to be used
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
    95
     * specifically for navigation; the given {@code Runnable} should thus be
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
    96
     * limited to calling {@link #goTo(boolean,Control,Navigable...)} and
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
    97
     * (briefly) handling any thrown exceptions.
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
    98
     * <p/>
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
    99
     * Note: If this method is called when the navigation thread is busy, the
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   100
     * given {@code Runnable} will be queued and run when the thread is
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   101
     * available.
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   102
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   103
     * @param	    r
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   104
     *		    the {@code Runnable} to run and handle any resulting
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   105
     *		    exceptions
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   106
     */
19
9c1f74f86687 2837 Minor spelling errors and inconsistencies
Stephen Talley <stephen.talley@sun.com>
parents: 0
diff changeset
   107
    public void asyncExec(Runnable r) {
30
0ad10e34fb31 3025 Thread pools should be named for better diagnostics
Stephen Talley <stephen.talley@sun.com>
parents: 21
diff changeset
   108
	threadPool.execute(r);
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   109
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   110
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   111
    /**
68
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   112
     * Runs the given {@link NavRunnable} on this {@code Navigator}'s navigation
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   113
     * thread and waits for it to complete.  Any exceptions thrown by {@code r}
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   114
     * are thrown here.
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   115
     * <p/>
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   116
     * See {@link #asyncExec}.
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   117
     *
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   118
     * @param	    r
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   119
     *		    the {@link NavRunnable} to run
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   120
     */
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   121
    public void asyncExecAndWait(final NavRunnable r)
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   122
	throws NavigationAbortedException, InvalidAddressException,
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   123
	MissingParameterException, InvalidParameterException {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   124
68
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   125
	if (isDispatchThread()) {
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   126
	    r.run();
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   127
	    return;
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   128
	}
712f02aa3c15 3348 After selecting existing login from new window, unable to close window
Stephen Talley <stephen.talley@sun.com>
parents: 60
diff changeset
   129
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   130
	final boolean[] done = {false};
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   131
	final Throwable[] throwable = {null};
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   132
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   133
	asyncExec(
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   134
	    new Runnable() {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   135
		@Override
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   136
		public void run() {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   137
		    try {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   138
			r.run();
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   139
		    } catch (Throwable t) {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   140
			throwable[0] = t;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   141
		    }
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   142
		    synchronized (done) {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   143
			done[0] = true;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   144
			done.notify();
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   145
		    }
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   146
		}
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   147
	    });
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   148
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   149
	// Sleep until nav thread is done
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   150
	synchronized (done) {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   151
	    while (!done[0]) {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   152
		try {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   153
		    done.wait();
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   154
		} catch (InterruptedException ignore) {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   155
		}
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   156
	    }
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   157
	}
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   158
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   159
	Throwable t = throwable[0];
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   160
	if (t != null) {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   161
	    if (t instanceof NavigationAbortedException)
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   162
		throw (NavigationAbortedException)t;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   163
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   164
	    if (t instanceof InvalidAddressException)
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   165
		throw (InvalidAddressException)t;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   166
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   167
	    if (t instanceof MissingParameterException)
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   168
		throw (MissingParameterException)t;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   169
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   170
	    if (t instanceof InvalidParameterException)
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   171
		throw (InvalidParameterException)t;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   172
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   173
	    if (t instanceof RuntimeException)
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   174
		throw (RuntimeException)t;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   175
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   176
	    if (t instanceof Error)
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   177
		throw (Error)t;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   178
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   179
	    // All Throwables should be accounted for
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   180
	    assert false;
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   181
	}
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   182
    }
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   183
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   184
    /**
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   185
     * Notifies all registered {@link NavigationListener}s that a navigation has
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   186
     * begun.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   187
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   188
    protected void fireNavigationStarted(NavigationEvent e) {
157
f4316b998c95 4857 all classes that handle event management should use EventListeners class
Stephen Talley <stephen.talley@sun.com>
parents: 156
diff changeset
   189
	listeners.navigationStarted(e);
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   190
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   191
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   192
    /**
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   193
     * Notifies all registered {@link NavigationListener}s that a navigation has
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   194
     * stopped.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   195
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   196
    protected void fireNavigationStopped(NavigationEvent e) {
157
f4316b998c95 4857 all classes that handle event management should use EventListeners class
Stephen Talley <stephen.talley@sun.com>
parents: 156
diff changeset
   197
	listeners.navigationStopped(e);
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   198
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   199
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   200
    /**
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   201
     * Returns the current {@link Control}, or {@code null} if the root element
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   202
     * of the navigation stack has not yet been set.
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   203
     */
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   204
    public Control getCurrentControl() {
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   205
	synchronized (stack) {
190
555203a2de79 5952 Stack API should conform to java.util.Dequeue specification
Stephen Talley <stephen.talley@sun.com>
parents: 157
diff changeset
   206
	    return stack.peekLast();
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   207
	}
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   208
    }
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   209
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   210
    /**
190
555203a2de79 5952 Stack API should conform to java.util.Dequeue specification
Stephen Talley <stephen.talley@sun.com>
parents: 157
diff changeset
   211
     * Gets a list of the elements of the current path, with the root element at
555203a2de79 5952 Stack API should conform to java.util.Dequeue specification
Stephen Talley <stephen.talley@sun.com>
parents: 157
diff changeset
   212
     * the beginning of the list.  This method is not thread-safe; it is up to
54
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   213
     * callers to ensure the that navigation is not currently modifying this
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   214
     * path.
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   215
     */
54
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   216
    @SuppressWarnings({"unchecked"})
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   217
    public List<Control> getPath() {
54
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   218
	return (List<Control>)stack.clone();
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   219
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   220
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   221
    /**
54
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   222
     * Gets the current path as a {@code String}.  This method is not
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   223
     * thread-safe; it is up to callers to ensure the that navigation is not
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   224
     * currently modifying this path.
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   225
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   226
    public String getPathString() {
54
ffbdd1a03fca 3305 consumers of Navigator's getPath subject to ConcurrentModificationExceptions
Stephen Talley <stephen.talley@sun.com>
parents: 40
diff changeset
   227
	return getPathString(stack);
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   228
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   229
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   230
    /**
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   231
     * Navigates to the {@link Control} identified by the given path.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   232
     *
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   233
     * @param	    cancel
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   234
     *		    {@code true} if the {@code Control}s, if any, that are
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   235
     *		    stopped as part of this navigation should be cancelled,
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   236
     *		    {@code false} otherwise; this parameter is passed along to
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   237
     *		    the {@link Control#stop} method
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   238
     *
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   239
     * @param	    relativeTo
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   240
     *		    a {@link Control} within the navigation stack to which
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   241
     *		    {@code path} is relative, or {@code null} if {@code path} is
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   242
     *		    absolute
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   243
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   244
     * @param	    path
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   245
     *		    the path (relative to {@code relativeTo}), or unspecified to
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   246
     *		    navigate up the stack to {@code relativeTo}; if the root of
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   247
     *		    this {@code Navigator} has not yet been set, the first
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   248
     *		    element of this path <strong>must</strong> be a {@link
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   249
     *		    Control}
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   250
     *
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   251
     * @return	    the previously current {@link Control}, or {@code null} if
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   252
     *		    the root {@link Control} of the navigation stack has not yet
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   253
     *		    been set
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   254
     *
40
d1412af1ae5b 3215 ActionAbortedException is used too broadly
Stephen Talley <stephen.talley@sun.com>
parents: 30
diff changeset
   255
     * @exception   NavigationAbortedException
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   256
     *		    if the navigation is vetoed
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   257
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   258
     * @exception   InvalidAddressException
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   259
     *		    if {@code path} does not refer to a valid address
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   260
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   261
     * @exception   MissingParameterException
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   262
     *		    if some {@link Control} in the process of navigation could
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   263
     *		    not be {@link Control#start started} due to a missing
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   264
     *		    intialization parameter
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   265
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   266
     * @exception   InvalidParameterException
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   267
     *		    if some {@link Control} in the process of navigation could
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   268
     *		    not be {@link Control#start started} due to an invalid
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   269
     *		    intialization parameter
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   270
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   271
     * @exception   IllegalArgumentException
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   272
     *		    if {@code relativeTo} is not in the navigation stack
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   273
     */
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   274
    public Control goTo(boolean cancel, Control relativeTo, Navigable... path)
40
d1412af1ae5b 3215 ActionAbortedException is used too broadly
Stephen Talley <stephen.talley@sun.com>
parents: 30
diff changeset
   275
	throws NavigationAbortedException, InvalidAddressException,
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   276
	MissingParameterException, InvalidParameterException {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   277
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   278
	assert isDispatchThread();
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   279
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   280
	synchronized (stack) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   281
	    // The original Control, before navigation
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   282
	    Control orig = getCurrentControl();
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   283
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   284
	    List<Control> stopped = new ArrayList<Control>();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   285
	    List<Control> started = new ArrayList<Control>();
261
56505bb0e870 8005 aborted navigation can result in blocked UI
Stephen Talley <stephen.talley@sun.com>
parents: 258
diff changeset
   286
	    boolean needStopEvent = false;
251
2d4060817fe2 7905 NavigationListeners that resize a window or handle UI flicker should not be tied to a specific Window
Stephen Talley <stephen.talley@sun.com>
parents: 248
diff changeset
   287
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   288
	    try {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   289
		boolean done = false;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   290
		while (!done) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   291
		    // Last absolute path
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   292
		    LinkedList<Navigable> laPath = new LinkedList<Navigable>();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   293
		    laPath.addAll(stack);
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   294
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   295
		    // Current absolute path
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   296
		    LinkedList<Navigable> caPath = new LinkedList<Navigable>();
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   297
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   298
		    if (relativeTo != null) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   299
			caPath.addAll(laPath);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   300
			try {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   301
			    // Remove path elements until relativeTo is at top
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   302
			    while (!((HasControl)caPath.getLast()).getControl().
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   303
				equals(relativeTo)) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   304
				caPath.removeLast();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   305
			    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   306
			} catch (NoSuchElementException e) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   307
			    throw new IllegalArgumentException(String.format(
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   308
				"Control not in navigation path: %s (%s)",
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   309
				relativeTo.getClass().getName(),
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   310
				relativeTo.getId()));
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   311
			}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   312
		    }
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   313
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   314
		    if (path.length != 0) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   315
			CollectionUtil.addAll(caPath, path);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   316
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   317
			// Remove unnecessary ".." segments
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   318
			normalize(caPath);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   319
		    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   320
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   321
		    List<Navigable> relPath = getRelativePath(laPath, caPath);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   322
		    if (!relPath.isEmpty()) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   323
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   324
			// Iterate through relPath, adding/removing elements
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   325
			// to/from laPath as appropriate
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   326
			for (Navigable nav : relPath) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   327
			    if (nav.getId().equals(PARENT_ID)) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   328
				try {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   329
				    laPath.removeLast();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   330
				} catch (NoSuchElementException e) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   331
				    throw new IllegalArgumentException(
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   332
					"\"..\" encountered with empty " +
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   333
					"navigation stack");
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   334
				}
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   335
			    } else {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   336
				Control newControl;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   337
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   338
				// If the Navigation stack has no root...
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   339
				if (laPath.isEmpty()) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   340
				    try {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   341
					newControl = (Control)nav;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   342
				    } catch (ClassCastException e) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   343
					throw new IllegalArgumentException(
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   344
					    "root-level Navigable \"" +
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   345
					    nav.getName() +
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   346
					    "\" must be a Control");
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   347
				    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   348
				} else {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   349
				    String id = nav.getId();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   350
				    Object last = laPath.getLast();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   351
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   352
				    // laPath elements are Controls or
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   353
				    // PendingControls
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   354
				    Control curControl =
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   355
					((HasControl)last).getControl();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   356
				    newControl = curControl.getChildControl(id);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   357
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   358
				    if (newControl == null) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   359
					throw new InvalidAddressException(
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   360
					    String.format("%s%s%s",
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   361
					    getPathString(laPath),
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   362
					    PATH_SEPARATOR, id));
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   363
				    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   364
				}
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   365
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   366
				PendingControl pair = new PendingControl(
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   367
				    newControl, nav.getParameters());
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   368
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   369
				laPath.add(pair);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   370
			    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   371
			}
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   372
		    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   373
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   374
		    @SuppressWarnings({"unchecked"})
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   375
		    List<PendingControl> rPath = (List<PendingControl>)(List)
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   376
			getRelativePath(stack, laPath);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   377
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   378
		    if (!rPath.isEmpty()) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   379
			List<PendingControl> roRPath =
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   380
			    Collections.unmodifiableList(rPath);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   381
			NavigationEvent event = new NavigationEvent(this,
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   382
			    roRPath);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   383
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   384
			fireNavigationStarted(event);
261
56505bb0e870 8005 aborted navigation can result in blocked UI
Stephen Talley <stephen.talley@sun.com>
parents: 258
diff changeset
   385
			needStopEvent = true;
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   386
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   387
			for (PendingControl pend : rPath) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   388
			    Control curControl = getCurrentControl();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   389
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   390
			    if (pend.getId().equals(PARENT_ID)) {
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   391
				curControl.stop(cancel);
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   392
				stopped.add(curControl);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   393
				stack.removeLast();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   394
				descendantStopped(curControl);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   395
			    } else {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   396
				Control newControl = pend.getControl();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   397
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   398
				newControl.start(this, pend.getParameters());
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   399
				started.add(newControl);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   400
				stack.add(newControl);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   401
				descendantStarted();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   402
			    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   403
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   404
			    if (System.getProperty("vpanels.debug.navigator") !=
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   405
				null) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   406
				System.out.printf("%s\n", getPathString());
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   407
			    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   408
			}
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   409
		    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   410
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   411
		    // Navigation is complete.	However, if the current
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   412
		    // Control's getForwardingPath returns a non-null value,
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   413
		    // invoke another round of navigation.
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   414
		    done = true;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   415
		    Control curControl = getCurrentControl();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   416
		    if (curControl != null) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   417
			Navigable[] forward = curControl.getForwardingPath();
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   418
			if (forward != null && forward.length != 0) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   419
			    // Is this path absolute?
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   420
			    if (forward[0] == null) {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   421
				relativeTo = null;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   422
				path = new Navigable[forward.length - 1];
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   423
				System.arraycopy(forward, 1, path, 0,
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   424
				    path.length);
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   425
			    } else {
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   426
				relativeTo = curControl;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   427
				path = forward;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   428
			    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   429
			    done = false;
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   430
			}
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   431
		    }
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   432
		}
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   433
	    } finally {
261
56505bb0e870 8005 aborted navigation can result in blocked UI
Stephen Talley <stephen.talley@sun.com>
parents: 258
diff changeset
   434
		if (needStopEvent) {
258
521fd086e813 7977 navigator: getForwardingPath should be called after Control is started
Stephen Talley <stephen.talley@sun.com>
parents: 251
diff changeset
   435
		    NavigationEvent event = new NavigationEvent(this,
251
2d4060817fe2 7905 NavigationListeners that resize a window or handle UI flicker should not be tied to a specific Window
Stephen Talley <stephen.talley@sun.com>
parents: 248
diff changeset
   436
			Collections.unmodifiableList(stopped),
2d4060817fe2 7905 NavigationListeners that resize a window or handle UI flicker should not be tied to a specific Window
Stephen Talley <stephen.talley@sun.com>
parents: 248
diff changeset
   437
			Collections.unmodifiableList(started));
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   438
		    fireNavigationStopped(event);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   439
		}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   440
	    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   441
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   442
	    return orig;
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   443
	}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   444
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   445
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   446
    /**
20
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   447
     * Asynchronously navigates to the {@link Control} identified by the
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   448
     * given path.  A wrapper around {@link #goTo(boolean,Control,Navigable...)}
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   449
     * that is run asynchronously using {@link #asyncExec}.
20
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   450
     */
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   451
    public void goToAsync(final boolean cancel, final Control relativeTo,
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   452
	final Navigable... path) {
20
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   453
	asyncExec(
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   454
	    new Runnable() {
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   455
		@Override
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   456
		public void run() {
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   457
		    try {
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   458
			goTo(cancel, relativeTo, path);
20
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   459
		    } catch (NavigationException ignore) {
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   460
		    }
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   461
		}
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   462
	    });
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   463
    }
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   464
5423319ed064 2853 Async navigation in serious need of factoring
David Powell <David.Powell@sun.com>
parents: 19
diff changeset
   465
    /**
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   466
     * Asynchronously navigates to the {@link Control} identified by the given
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   467
     * path, returning only when navigation is complete.  A wrapper around
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   468
     * {@link #goTo(boolean,Control,Navigable...)} that is run asynchronously
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   469
     * using {@link #asyncExecAndWait}.
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   470
     */
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   471
    public void goToAsyncAndWait(final boolean cancel, final Control relativeTo,
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   472
	final Navigable... path) throws NavigationAbortedException,
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   473
	InvalidAddressException, MissingParameterException,
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   474
	InvalidParameterException {
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   475
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   476
	asyncExecAndWait(
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   477
	    new NavRunnable() {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   478
		@Override
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   479
		public void run()
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   480
		    throws NavigationAbortedException, InvalidAddressException,
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   481
		    MissingParameterException, InvalidParameterException {
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   482
302
ac70675de834 9318 Navigator/Control should distinguish between cancel and non-cancel navigations
Stephen Talley <stephen.talley@sun.com>
parents: 275
diff changeset
   483
		    goTo(cancel, relativeTo, path);
60
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   484
		}
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   485
	    });
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   486
    }
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   487
9a179bed654e 3334 navigation should be run solely on navigation thread
Stephen Talley <stephen.talley@sun.com>
parents: 59
diff changeset
   488
    /**
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   489
     * Determines whether the current thread is the navigation dispatch thread.
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   490
     * The navigation dispatch thread may change over time, but only one is
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   491
     * alive at a time.
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   492
     */
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   493
    public boolean isDispatchThread() {
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   494
	return Thread.currentThread() == dispatchThread;
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   495
    }
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   496
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   497
    /**
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   498
     * Removes a {@link NavigationListener} from notification of when navigation
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   499
     * is stopped and started.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   500
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   501
    public boolean removeNavigationListener(NavigationListener l) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   502
	return listeners.remove(l);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   503
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   504
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   505
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   506
    // Private methods
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   507
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   508
248
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   509
    private void descendantStarted() {
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   510
	int n = stack.size();
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   511
	for (int i = n - 2; i >= 0; i--) {
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   512
	    Control alert = stack.get(i);
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   513
	    Control[] path = new Control[n - i - 1];
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   514
	    for (int j = i + 1; j < n; j++) {
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   515
		path[j - i - 1] = stack.get(j);
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   516
	    }
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   517
	    alert.descendantStarted(path);
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   518
	}
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   519
    }
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   520
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   521
    private void descendantStopped(Control control) {
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   522
	int n = stack.size();
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   523
	for (int i = n - 1; i >= 0; i--) {
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   524
	    Control alert = stack.get(i);
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   525
	    Control[] path = new Control[n - i];
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   526
	    path[path.length - 1] = control;
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   527
	    for (int j = i + 1; j < n; j++) {
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   528
		path[j - i - 1] = stack.get(j);
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   529
	    }
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   530
	    alert.descendantStopped(path);
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   531
	}
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   532
    }
d947462c8e37 7851 Control should support notification of descendants starting/stopping
Stephen Talley <stephen.talley@sun.com>
parents: 247
diff changeset
   533
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   534
    /**
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   535
     * Gets the relative path between the given absolute paths.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   536
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   537
     * @param	    fromPath
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   538
     *		    an absolute source path
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   539
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   540
     * @param	    toPath
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   541
     *		    an absolute destination path
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   542
     *
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   543
     * @return	    a relative path from the current path to the given path
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   544
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   545
    private List<Navigable> getRelativePath(
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   546
	List<? extends Navigable> fromPath,
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   547
	List<? extends Navigable> toPath) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   548
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   549
	List<Navigable> rPath = new ArrayList<Navigable>();
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   550
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   551
	// Determine branching index
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   552
	int branch = 0;
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   553
	while (branch < fromPath.size() && branch < toPath.size() &&
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   554
	    Navigable.Util.equals(fromPath.get(branch), toPath.get(branch))) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   555
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   556
	    branch++;
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   557
	}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   558
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   559
	for (int i = fromPath.size() - 1; i >= branch; i--) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   560
	    rPath.add(PendingControl.PARENT);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   561
	}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   562
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   563
	for (int i = branch; i < toPath.size(); i++) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   564
	    rPath.add(toPath.get(i));
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   565
	}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   566
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   567
	return rPath;
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   568
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   569
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   570
    /**
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   571
     * Removes each ".." segment and preceding non-".." segment the given path.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   572
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   573
    private void normalize(List<? extends HasId> path) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   574
	for (int i = 1; i < path.size(); i++) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   575
	    if (path.get(i).getId().equals(PARENT_ID) &&
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   576
		!path.get(i - 1).getId().equals(PARENT_ID)) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   577
		path.remove(i--);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   578
		path.remove(i--);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   579
	    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   580
	}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   581
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   582
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   583
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   584
    // Static methods
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   585
    //
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   586
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   587
    /**
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   588
     * Gets the given path as a {@code String}.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   589
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   590
    public static String getPathString(Collection<? extends Navigable> path) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   591
	StringBuffer buffer = new StringBuffer();
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   592
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   593
	for (Navigable nav : path) {
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   594
	    buffer.append(PATH_SEPARATOR).append(Control.encode(
133
e1112f707f32 4258 navigator shouldn't navigate to root control in constructor
Stephen Talley <stephen.talley@sun.com>
parents: 68
diff changeset
   595
		nav.getId(), nav.getParameters()));
0
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   596
	}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   597
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   598
	return buffer.toString();
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   599
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   600
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   601
    /**
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   602
     * Determines whether the given path is absolute.  If the given path starts
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   603
     * with PATH_SEPARATOR, it is considered absolute.
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   604
     */
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   605
    public static boolean isAbsolute(String path) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   606
	return path.startsWith(PATH_SEPARATOR);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   607
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   608
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   609
    public static SimpleNavigable[] toArray(String path) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   610
	path = path.replaceFirst(
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   611
	    "^(" + Pattern.quote(PATH_SEPARATOR) + ")+", "");
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   612
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   613
	String[] parts = path.split(PATH_SEPARATOR, 0);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   614
	SimpleNavigable[] elements = new SimpleNavigable[parts.length];
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   615
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   616
	for (int i = 0; i < parts.length; i++) {
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   617
	    elements[i] = Control.decode(parts[i]);
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   618
	}
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   619
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   620
	return elements;
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   621
    }
62ac12e07fc0 Initial integration.
David Powell <David.Powell@sun.com>
parents:
diff changeset
   622
}