jdk/src/share/classes/javax/swing/text/ElementIterator.java
author sherman
Tue, 30 Aug 2011 11:53:11 -0700
changeset 10419 12c063b39232
parent 5506 202f599c92aa
child 21278 ef8a3a2a72f2
permissions -rw-r--r--
7084245: Update usages of InternalError to use exception chaining Summary: to use new InternalError constructor with cause chainning Reviewed-by: alanb, ksrini, xuelei, neugens Contributed-by: sebastian.sickelmann@gmx.de
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     1
/*
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
     2
 * Copyright (c) 1998, 2008, Oracle and/or its affiliates. All rights reserved.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     3
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
90ce3da70b43 Initial load
duke
parents:
diff changeset
     4
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
     5
 * This code is free software; you can redistribute it and/or modify it
90ce3da70b43 Initial load
duke
parents:
diff changeset
     6
 * under the terms of the GNU General Public License version 2 only, as
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
     7
 * published by the Free Software Foundation.  Oracle designates this
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
     8
 * particular file as subject to the "Classpath" exception as provided
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
     9
 * by Oracle in the LICENSE file that accompanied this code.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    10
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    11
 * This code is distributed in the hope that it will be useful, but WITHOUT
90ce3da70b43 Initial load
duke
parents:
diff changeset
    12
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
90ce3da70b43 Initial load
duke
parents:
diff changeset
    13
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
90ce3da70b43 Initial load
duke
parents:
diff changeset
    14
 * version 2 for more details (a copy is included in the LICENSE file that
90ce3da70b43 Initial load
duke
parents:
diff changeset
    15
 * accompanied this code).
90ce3da70b43 Initial load
duke
parents:
diff changeset
    16
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    17
 * You should have received a copy of the GNU General Public License version
90ce3da70b43 Initial load
duke
parents:
diff changeset
    18
 * 2 along with this work; if not, write to the Free Software Foundation,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    19
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    20
 *
5506
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
    21
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
    22
 * or visit www.oracle.com if you need additional information or have any
202f599c92aa 6943119: Rebrand source copyright notices
ohair
parents: 1639
diff changeset
    23
 * questions.
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    24
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    25
90ce3da70b43 Initial load
duke
parents:
diff changeset
    26
package javax.swing.text;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    27
90ce3da70b43 Initial load
duke
parents:
diff changeset
    28
import java.util.Stack;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    29
import java.util.Enumeration;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    30
90ce3da70b43 Initial load
duke
parents:
diff changeset
    31
/**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    32
 * <p>
90ce3da70b43 Initial load
duke
parents:
diff changeset
    33
 * ElementIterator, as the name suggests, iteratates over the Element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    34
 * tree.  The constructor can be invoked with either Document or an Element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    35
 * as an argument.  If the constructor is invoked with a Document as an
90ce3da70b43 Initial load
duke
parents:
diff changeset
    36
 * argument then the root of the iteration is the return value of
90ce3da70b43 Initial load
duke
parents:
diff changeset
    37
 * document.getDefaultRootElement().
90ce3da70b43 Initial load
duke
parents:
diff changeset
    38
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    39
 * The iteration happens in a depth-first manner.  In terms of how
90ce3da70b43 Initial load
duke
parents:
diff changeset
    40
 * boundary conditions are handled:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    41
 * a) if next() is called before first() or current(), the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    42
 *    root will be returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    43
 * b) next() returns null to indicate the end of the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    44
 * c) previous() returns null when the current element is the root
90ce3da70b43 Initial load
duke
parents:
diff changeset
    45
 *    or next() has returned null.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    46
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    47
 * The ElementIterator does no locking of the Element tree. This means
90ce3da70b43 Initial load
duke
parents:
diff changeset
    48
 * that it does not track any changes.  It is the responsibility of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    49
 * user of this class, to ensure that no changes happen during element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    50
 * iteration.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    51
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    52
 * Simple usage example:
90ce3da70b43 Initial load
duke
parents:
diff changeset
    53
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    54
 *    public void iterate() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    55
 *        ElementIterator it = new ElementIterator(root);
90ce3da70b43 Initial load
duke
parents:
diff changeset
    56
 *        Element elem;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    57
 *        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    58
 *           if ((elem = next()) != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    59
 *               // process element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    60
 *               System.out.println("elem: " + elem.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
    61
 *           } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    62
 *               break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    63
 *           }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    64
 *        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    65
 *    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
    66
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    67
 * @author Sunita Mani
90ce3da70b43 Initial load
duke
parents:
diff changeset
    68
 *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    69
 */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    70
90ce3da70b43 Initial load
duke
parents:
diff changeset
    71
public class ElementIterator implements Cloneable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    72
90ce3da70b43 Initial load
duke
parents:
diff changeset
    73
90ce3da70b43 Initial load
duke
parents:
diff changeset
    74
    private Element root;
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
    75
    private Stack<StackItem> elementStack = null;
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
    76
90ce3da70b43 Initial load
duke
parents:
diff changeset
    77
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    78
     * The StackItem class stores the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    79
     * as well as a child index.  If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
    80
     * index is -1, then the element represented
90ce3da70b43 Initial load
duke
parents:
diff changeset
    81
     * on the stack is the element itself.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    82
     * Otherwise, the index functions as as index
90ce3da70b43 Initial load
duke
parents:
diff changeset
    83
     * into the vector of children of the element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    84
     * In this case, the item on the stack
90ce3da70b43 Initial load
duke
parents:
diff changeset
    85
     * represents the "index"th child of the element
90ce3da70b43 Initial load
duke
parents:
diff changeset
    86
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
    87
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    88
    private class StackItem implements Cloneable {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    89
        Element item;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    90
        int childIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    91
90ce3da70b43 Initial load
duke
parents:
diff changeset
    92
        private StackItem(Element elem) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
    93
            /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
    94
             * -1 index implies a self reference,
90ce3da70b43 Initial load
duke
parents:
diff changeset
    95
             * as opposed to an index into its
90ce3da70b43 Initial load
duke
parents:
diff changeset
    96
             * list of children.
90ce3da70b43 Initial load
duke
parents:
diff changeset
    97
             */
90ce3da70b43 Initial load
duke
parents:
diff changeset
    98
            this.item = elem;
90ce3da70b43 Initial load
duke
parents:
diff changeset
    99
            this.childIndex = -1;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   100
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   101
90ce3da70b43 Initial load
duke
parents:
diff changeset
   102
        private void incrementIndex() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   103
            childIndex++;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   104
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   105
90ce3da70b43 Initial load
duke
parents:
diff changeset
   106
        private Element getElement() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   107
            return item;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   108
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   109
90ce3da70b43 Initial load
duke
parents:
diff changeset
   110
        private int getIndex() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   111
            return childIndex;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   112
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   113
90ce3da70b43 Initial load
duke
parents:
diff changeset
   114
        protected Object clone() throws java.lang.CloneNotSupportedException {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   115
            return super.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   116
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   117
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   118
90ce3da70b43 Initial load
duke
parents:
diff changeset
   119
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   120
     * Creates a new ElementIterator. The
90ce3da70b43 Initial load
duke
parents:
diff changeset
   121
     * root element is taken to get the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   122
     * default root element of the document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   123
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   124
     * @param document a Document.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   125
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   126
    public ElementIterator(Document document) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   127
        root = document.getDefaultRootElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   128
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   129
90ce3da70b43 Initial load
duke
parents:
diff changeset
   130
90ce3da70b43 Initial load
duke
parents:
diff changeset
   131
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   132
     * Creates a new ElementIterator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   133
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   134
     * @param root the root Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   135
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   136
    public ElementIterator(Element root) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   137
        this.root = root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   138
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   139
90ce3da70b43 Initial load
duke
parents:
diff changeset
   140
90ce3da70b43 Initial load
duke
parents:
diff changeset
   141
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   142
     * Clones the ElementIterator.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   143
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   144
     * @return a cloned ElementIterator Object.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   145
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   146
    public synchronized Object clone() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   147
90ce3da70b43 Initial load
duke
parents:
diff changeset
   148
        try {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   149
            ElementIterator it = new ElementIterator(root);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   150
            if (elementStack != null) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   151
                it.elementStack = new Stack<StackItem>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   152
                for (int i = 0; i < elementStack.size(); i++) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   153
                    StackItem item = elementStack.elementAt(i);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   154
                    StackItem clonee = (StackItem)item.clone();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   155
                    it.elementStack.push(clonee);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   156
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   157
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   158
            return it;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   159
        } catch (CloneNotSupportedException e) {
10419
12c063b39232 7084245: Update usages of InternalError to use exception chaining
sherman
parents: 5506
diff changeset
   160
            throw new InternalError(e);
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   161
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   162
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   163
90ce3da70b43 Initial load
duke
parents:
diff changeset
   164
90ce3da70b43 Initial load
duke
parents:
diff changeset
   165
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   166
     * Fetches the first element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   167
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   168
     * @return an Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   169
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   170
    public Element first() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   171
        // just in case...
90ce3da70b43 Initial load
duke
parents:
diff changeset
   172
        if (root == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   173
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   174
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   175
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   176
        elementStack = new Stack<StackItem>();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   177
        if (root.getElementCount() != 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   178
            elementStack.push(new StackItem(root));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   179
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   180
        return root;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   181
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   182
90ce3da70b43 Initial load
duke
parents:
diff changeset
   183
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   184
     * Fetches the current depth of element tree.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   185
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   186
     * @return the depth.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   187
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   188
    public int depth() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   189
        if (elementStack == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   190
            return 0;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   191
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   192
        return elementStack.size();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   193
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   194
90ce3da70b43 Initial load
duke
parents:
diff changeset
   195
90ce3da70b43 Initial load
duke
parents:
diff changeset
   196
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   197
     * Fetches the current Element.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   198
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   199
     * @return element on top of the stack or
90ce3da70b43 Initial load
duke
parents:
diff changeset
   200
     *          <code>null</code> if the root element is <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   201
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   202
    public Element current() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   203
90ce3da70b43 Initial load
duke
parents:
diff changeset
   204
        if (elementStack == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   205
            return first();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   206
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   207
90ce3da70b43 Initial load
duke
parents:
diff changeset
   208
        /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   209
          get a handle to the element on top of the stack.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   210
        */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   211
        if (! elementStack.empty()) {
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   212
            StackItem item = elementStack.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   213
            Element elem = item.getElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   214
            int index = item.getIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   215
            // self reference
90ce3da70b43 Initial load
duke
parents:
diff changeset
   216
            if (index == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   217
                return elem;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   218
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   219
            // return the child at location "index".
90ce3da70b43 Initial load
duke
parents:
diff changeset
   220
            return elem.getElement(index);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   221
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   222
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   223
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   224
90ce3da70b43 Initial load
duke
parents:
diff changeset
   225
90ce3da70b43 Initial load
duke
parents:
diff changeset
   226
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   227
     * Fetches the next Element. The strategy
90ce3da70b43 Initial load
duke
parents:
diff changeset
   228
     * used to locate the next element is
90ce3da70b43 Initial load
duke
parents:
diff changeset
   229
     * a depth-first search.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   230
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   231
     * @return the next element or <code>null</code>
90ce3da70b43 Initial load
duke
parents:
diff changeset
   232
     *          at the end of the list.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   233
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   234
    public Element next() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   235
90ce3da70b43 Initial load
duke
parents:
diff changeset
   236
        /* if current() has not been invoked
90ce3da70b43 Initial load
duke
parents:
diff changeset
   237
           and next is invoked, the very first
90ce3da70b43 Initial load
duke
parents:
diff changeset
   238
           element will be returned. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   239
        if (elementStack == null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   240
            return first();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   241
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   242
90ce3da70b43 Initial load
duke
parents:
diff changeset
   243
        // no more elements
90ce3da70b43 Initial load
duke
parents:
diff changeset
   244
        if (elementStack.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   245
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   246
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   247
90ce3da70b43 Initial load
duke
parents:
diff changeset
   248
        // get a handle to the element on top of the stack
90ce3da70b43 Initial load
duke
parents:
diff changeset
   249
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   250
        StackItem item = elementStack.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   251
        Element elem = item.getElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   252
        int index = item.getIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   253
90ce3da70b43 Initial load
duke
parents:
diff changeset
   254
        if (index+1 < elem.getElementCount()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   255
            Element child = elem.getElement(index+1);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   256
            if (child.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   257
                /* In this case we merely want to increment
90ce3da70b43 Initial load
duke
parents:
diff changeset
   258
                   the child index of the item on top of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   259
                   stack.*/
90ce3da70b43 Initial load
duke
parents:
diff changeset
   260
                item.incrementIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   261
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   262
                /* In this case we need to push the child(branch)
90ce3da70b43 Initial load
duke
parents:
diff changeset
   263
                   on the stack so that we can iterate over its
90ce3da70b43 Initial load
duke
parents:
diff changeset
   264
                   children. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   265
                elementStack.push(new StackItem(child));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   266
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   267
            return child;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   268
        } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   269
            /* No more children for the item on top of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   270
               stack therefore pop the stack. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   271
            elementStack.pop();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   272
            if (!elementStack.isEmpty()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   273
                /* Increment the child index for the item that
90ce3da70b43 Initial load
duke
parents:
diff changeset
   274
                   is now on top of the stack. */
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   275
                StackItem top = elementStack.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   276
                top.incrementIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   277
                /* We now want to return its next child, therefore
90ce3da70b43 Initial load
duke
parents:
diff changeset
   278
                   call next() recursively. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   279
                return next();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   280
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   281
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   282
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   283
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   284
90ce3da70b43 Initial load
duke
parents:
diff changeset
   285
90ce3da70b43 Initial load
duke
parents:
diff changeset
   286
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   287
     * Fetches the previous Element. If howver the current
90ce3da70b43 Initial load
duke
parents:
diff changeset
   288
     * element is the last element, or the current element
90ce3da70b43 Initial load
duke
parents:
diff changeset
   289
     * is null, then null is returned.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   290
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   291
     * @return previous <code>Element</code> if available
90ce3da70b43 Initial load
duke
parents:
diff changeset
   292
     *
90ce3da70b43 Initial load
duke
parents:
diff changeset
   293
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   294
    public Element previous() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   295
90ce3da70b43 Initial load
duke
parents:
diff changeset
   296
        int stackSize;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   297
        if (elementStack == null || (stackSize = elementStack.size()) == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   298
            return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   299
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   300
90ce3da70b43 Initial load
duke
parents:
diff changeset
   301
        // get a handle to the element on top of the stack
90ce3da70b43 Initial load
duke
parents:
diff changeset
   302
        //
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   303
        StackItem item = elementStack.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   304
        Element elem = item.getElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   305
        int index = item.getIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   306
90ce3da70b43 Initial load
duke
parents:
diff changeset
   307
        if (index > 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   308
            /* return child at previous index. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   309
            return getDeepestLeaf(elem.getElement(--index));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   310
        } else if (index == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   311
            /* this implies that current is the element's
90ce3da70b43 Initial load
duke
parents:
diff changeset
   312
               first child, therefore previous is the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   313
               element itself. */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   314
            return elem;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   315
        } else if (index == -1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   316
            if (stackSize == 1) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   317
                // current is the root, nothing before it.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   318
                return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   319
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   320
            /* We need to return either the item
90ce3da70b43 Initial load
duke
parents:
diff changeset
   321
               below the top item or one of the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   322
               former's children. */
1287
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   323
            StackItem top = elementStack.pop();
a04aca99c77a 6722802: Code improvement and warnings removing from the javax.swing.text package
rupashka
parents: 2
diff changeset
   324
            item = elementStack.peek();
2
90ce3da70b43 Initial load
duke
parents:
diff changeset
   325
90ce3da70b43 Initial load
duke
parents:
diff changeset
   326
            // restore the top item.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   327
            elementStack.push(top);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   328
            elem = item.getElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   329
            index = item.getIndex();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   330
            return ((index == -1) ? elem : getDeepestLeaf(elem.getElement
90ce3da70b43 Initial load
duke
parents:
diff changeset
   331
                                                          (index)));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   332
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   333
        // should never get here.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   334
        return null;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   335
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   336
90ce3da70b43 Initial load
duke
parents:
diff changeset
   337
    /**
90ce3da70b43 Initial load
duke
parents:
diff changeset
   338
     * Returns the last child of <code>parent</code> that is a leaf. If the
90ce3da70b43 Initial load
duke
parents:
diff changeset
   339
     * last child is a not a leaf, this method is called with the last child.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   340
     */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   341
    private Element getDeepestLeaf(Element parent) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   342
        if (parent.isLeaf()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   343
            return parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   344
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   345
        int childCount = parent.getElementCount();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   346
        if (childCount == 0) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   347
            return parent;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   348
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   349
        return getDeepestLeaf(parent.getElement(childCount - 1));
90ce3da70b43 Initial load
duke
parents:
diff changeset
   350
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   351
90ce3da70b43 Initial load
duke
parents:
diff changeset
   352
    /*
90ce3da70b43 Initial load
duke
parents:
diff changeset
   353
      Iterates through the element tree and prints
90ce3da70b43 Initial load
duke
parents:
diff changeset
   354
      out each element and its attributes.
90ce3da70b43 Initial load
duke
parents:
diff changeset
   355
    */
90ce3da70b43 Initial load
duke
parents:
diff changeset
   356
    private void dumpTree() {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   357
90ce3da70b43 Initial load
duke
parents:
diff changeset
   358
        Element elem;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   359
        while (true) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   360
            if ((elem = next()) != null) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   361
                System.out.println("elem: " + elem.getName());
90ce3da70b43 Initial load
duke
parents:
diff changeset
   362
                AttributeSet attr = elem.getAttributes();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   363
                String s = "";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   364
                Enumeration names = attr.getAttributeNames();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   365
                while (names.hasMoreElements()) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   366
                    Object key = names.nextElement();
90ce3da70b43 Initial load
duke
parents:
diff changeset
   367
                    Object value = attr.getAttribute(key);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   368
                    if (value instanceof AttributeSet) {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   369
                        // don't go recursive
90ce3da70b43 Initial load
duke
parents:
diff changeset
   370
                        s = s + key + "=**AttributeSet** ";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   371
                    } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   372
                        s = s + key + "=" + value + " ";
90ce3da70b43 Initial load
duke
parents:
diff changeset
   373
                    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   374
                }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   375
                System.out.println("attributes: " + s);
90ce3da70b43 Initial load
duke
parents:
diff changeset
   376
            } else {
90ce3da70b43 Initial load
duke
parents:
diff changeset
   377
                break;
90ce3da70b43 Initial load
duke
parents:
diff changeset
   378
            }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   379
        }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   380
    }
90ce3da70b43 Initial load
duke
parents:
diff changeset
   381
}