1 /*
2  * Copyright (c) 1998, 2011, Oracle and/or its affiliates. All rights reserved.
3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
4  *
5  * This code is free software; you can redistribute it and/or modify it
6  * under the terms of the GNU General Public License version 2 only, as
7  * published by the Free Software Foundation.  Oracle designates this
8  * particular file as subject to the "Classpath" exception as provided
9  * by Oracle in the LICENSE file that accompanied this code.
10  *
11  * This code is distributed in the hope that it will be useful, but WITHOUT
12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
14  * version 2 for more details (a copy is included in the LICENSE file that
15  * accompanied this code).
16  *
17  * You should have received a copy of the GNU General Public License version
18  * 2 along with this work; if not, write to the Free Software Foundation,
19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20  *
21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22  * or visit www.oracle.com if you need additional information or have any
23  * questions.
24  */
25 
26 /*
27  * This source code is provided to illustrate the usage of a given feature
28  * or technique and has been deliberately simplified. Additional steps
29  * required for a production-quality application, such as security checks,
30  * input validation and proper error handling, might not be present in
31  * this sample code.
32  */
33 
34 
35 package com.sun.tools.example.debug.tty;
36 
37 import com.sun.jdi.ThreadGroupReference;
38 import java.util.List;
39 import java.util.Stack;
40 import java.util.ArrayList;
41 import java.util.Iterator;
42 
43 /**
44  * Descend the tree of thread groups.
45  * @author Robert G. Field
46  */
47 class ThreadGroupIterator implements Iterator<ThreadGroupReference> {
48     private final Stack<Iterator<ThreadGroupReference>> stack = new Stack<Iterator<ThreadGroupReference>>();
49 
ThreadGroupIterator(List<ThreadGroupReference> tgl)50     ThreadGroupIterator(List<ThreadGroupReference> tgl) {
51         push(tgl);
52     }
53 
ThreadGroupIterator(ThreadGroupReference tg)54     ThreadGroupIterator(ThreadGroupReference tg) {
55         List<ThreadGroupReference> tgl = new ArrayList<ThreadGroupReference>();
56         tgl.add(tg);
57         push(tgl);
58     }
59 
ThreadGroupIterator()60     ThreadGroupIterator() {
61         this(Env.vm().topLevelThreadGroups());
62     }
63 
top()64     private Iterator<ThreadGroupReference> top() {
65         return stack.peek();
66     }
67 
68     /**
69      * The invariant in this class is that the top iterator
70      * on the stack has more elements.  If the stack is
71      * empty, there is no top.  This method assures
72      * this invariant.
73      */
push(List<ThreadGroupReference> tgl)74     private void push(List<ThreadGroupReference> tgl) {
75         stack.push(tgl.iterator());
76         while (!stack.isEmpty() && !top().hasNext()) {
77             stack.pop();
78         }
79     }
80 
81     @Override
hasNext()82     public boolean hasNext() {
83         return !stack.isEmpty();
84     }
85 
86     @Override
next()87     public ThreadGroupReference next() {
88         return nextThreadGroup();
89     }
90 
nextThreadGroup()91     public ThreadGroupReference nextThreadGroup() {
92         ThreadGroupReference tg = top().next();
93         push(tg.threadGroups());
94         return tg;
95     }
96 
97     @Override
remove()98     public void remove() {
99         throw new UnsupportedOperationException();
100     }
101 
find(String name)102     static ThreadGroupReference find(String name) {
103         ThreadGroupIterator tgi = new ThreadGroupIterator();
104         while (tgi.hasNext()) {
105             ThreadGroupReference tg = tgi.nextThreadGroup();
106             if (tg.name().equals(name)) {
107                 return tg;
108             }
109         }
110         return null;
111     }
112 
113 }
114