KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > nextapp > echo2 > testapp > thousandmonkeys > Monkey


1 /*
2  * This file is part of the Echo Web Application Framework (hereinafter "Echo").
3  * Copyright (C) 2002-2005 NextApp, Inc.
4  *
5  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6  *
7  * The contents of this file are subject to the Mozilla Public License Version
8  * 1.1 (the "License"); you may not use this file except in compliance with
9  * the License. You may obtain a copy of the License at
10  * http://www.mozilla.org/MPL/
11  *
12  * Software distributed under the License is distributed on an "AS IS" basis,
13  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
14  * for the specific language governing rights and limitations under the
15  * License.
16  *
17  * Alternatively, the contents of this file may be used under the terms of
18  * either the GNU General Public License Version 2 or later (the "GPL"), or
19  * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
20  * in which case the provisions of the GPL or the LGPL are applicable instead
21  * of those above. If you wish to allow use of your version of this file only
22  * under the terms of either the GPL or the LGPL, and not to allow others to
23  * use your version of this file under the terms of the MPL, indicate your
24  * decision by deleting the provisions above and replace them with the notice
25  * and other provisions required by the GPL or the LGPL. If you do not delete
26  * the provisions above, a recipient may use your version of this file under
27  * the terms of any one of the MPL, the GPL or the LGPL.
28  */

29
30 package nextapp.echo2.testapp.thousandmonkeys;
31
32 import java.util.ArrayList JavaDoc;
33 import java.util.List JavaDoc;
34
35 import nextapp.echo2.app.CheckBox;
36 import nextapp.echo2.app.Column;
37 import nextapp.echo2.app.Component;
38 import nextapp.echo2.app.ContentPane;
39 import nextapp.echo2.app.Grid;
40 import nextapp.echo2.app.IllegalChildException;
41 import nextapp.echo2.app.ListBox;
42 import nextapp.echo2.app.PasswordField;
43 import nextapp.echo2.app.RadioButton;
44 import nextapp.echo2.app.Row;
45 import nextapp.echo2.app.SelectField;
46 import nextapp.echo2.app.SplitPane;
47 import nextapp.echo2.app.TextArea;
48 import nextapp.echo2.app.TextField;
49 import nextapp.echo2.app.WindowPane;
50 import nextapp.echo2.testapp.thousandmonkeys.factories.ButtonFactory;
51 import nextapp.echo2.testapp.thousandmonkeys.factories.GenericFactory;
52 import nextapp.echo2.testapp.thousandmonkeys.factories.LabelFactory;
53
54 /**
55  * A "Monkey" randomly adds, updates, and removes <code>Component</code>s from
56  * the application.
57  * Note: yes, there is only one monkey per application (you'll need 1000
58  * browser clients to truly achieve 1000 monkeys).
59  */

60 public class Monkey {
61     
62     private static final ComponentFactory[] componentFactories = new ComponentFactory[]{
63         new ButtonFactory(),
64         new GenericFactory(CheckBox.class),
65         new GenericFactory(Column.class),
66         new GenericFactory(ContentPane.class),
67         new GenericFactory(Grid.class),
68         new LabelFactory(),
69         new GenericFactory(ListBox.class),
70         new GenericFactory(PasswordField.class),
71         new GenericFactory(RadioButton.class),
72         new GenericFactory(Row.class),
73         new GenericFactory(SelectField.class),
74         new GenericFactory(SplitPane.class),
75         new GenericFactory(TextField.class),
76         new GenericFactory(TextArea.class),
77         new GenericFactory(WindowPane.class)
78     };
79     
80     /**
81      * The maximum number of children to add to the root
82      * <code>ContentPane</code>.
83      */

84     private static final int MAX_CONTENT_PANE_CHILDREN = 5;
85
86     /**
87      * The minimum number of add operations to perform per iteration.
88      */

89     private static final int MIN_ADDS = 0;
90
91     /**
92      * The maximum number of add operations to perform per iteration.
93      */

94     private static final int MAX_ADDS = 20;
95
96     /**
97      * The minimum number of remove operations to perform per iteration.
98      */

99     private static final int MIN_REMOVES = 0;
100
101     /**
102      * The maximum number of remove operations to perform per iteration.
103      */

104     private static final int MAX_REMOVES = 12;
105
106     /**
107      * The root <code>ContentPane</code> to which children should be added
108      * (will never be removed).
109      */

110     private ContentPane contentPane;
111     
112     /**
113      * List of all potential parent <code>Component</code>s.
114      */

115     private List JavaDoc components = new ArrayList JavaDoc();
116     
117     /**
118      * Creates a new <code>Monkey</code>.
119      *
120      * @param contentPane the root <code>ContentPane</code> to which children
121      * should be added (will never be removed)
122      */

123     public Monkey(ContentPane contentPane) {
124         this.contentPane = contentPane;
125     }
126     
127     /**
128      * Creates a random <code>Component</code> and adds it beneath a random
129      * parent.
130      */

131     private void doAdd() {
132         int addParentIndex;
133         if (components.size() < MAX_CONTENT_PANE_CHILDREN) {
134             addParentIndex = ((int) Math.random() * (components.size() + 1)) - 1;
135         } else {
136             addParentIndex = ((int) Math.random() * components.size());
137         }
138         ComponentFactory componentFactory = componentFactories[((int) (Math.random() * componentFactories.length))];
139         Component child = componentFactory.newInstance();
140         
141         for (int i = 0; i < 5; ++i) {
142             Component parent = addParentIndex == -1 ? contentPane : (Component) components.get(addParentIndex);
143             try {
144                 parent.add(child);
145                 components.add(child);
146                 return;
147             } catch (IllegalChildException ex) { }
148         }
149     }
150     
151     /**
152      * Removes a random <code>Component</code> from the hierarchy.
153      */

154     private void doRemove() {
155         if (components.size() == 0) {
156             // No components to remove.
157
return;
158         }
159         Component child = (Component) components.get((int) (Math.random() * components.size()));
160         child.getParent().remove(child);
161         recursiveRemoveComponentFromList(child);
162     }
163     
164     /**
165      * Performs a single iteration, potentially adding, removing, and/or
166      * updating several <code>Component</code>s.
167      */

168     public void iterate() {
169         int removes = ((int) (Math.random() * (1 + MAX_REMOVES - MIN_REMOVES))) + MIN_REMOVES;
170         for (int i = 0; i < removes; ++i) {
171             doRemove();
172         }
173
174         int adds = ((int) (Math.random() * (1 + MAX_ADDS - MIN_ADDS))) + MIN_ADDS;
175         for (int i = 0; i < adds; ++i) {
176             doAdd();
177         }
178         System.err.println(components.size());
179     }
180     
181     /**
182      * Recursively removes a <code>Component</code> and its descendants from
183      * the list of eligible parents. This operation is performed due to the
184      * <code>Component</code> having been deleted.
185      *
186      * @param component the deleted <code>Component</code>
187      */

188     private void recursiveRemoveComponentFromList(Component component) {
189         components.remove(component);
190         Component[] children = component.getComponents();
191         for (int i = 0; i < children.length; ++i) {
192             recursiveRemoveComponentFromList(children[i]);
193         }
194     }
195 }
196
Popular Tags