View Javadoc

1   /**
2    *
3    * Copyright 2005 The Apache Software Foundation
4    *
5    *  Licensed under the Apache License, Version 2.0 (the "License");
6    *  you may not use this file except in compliance with the License.
7    *  You may obtain a copy of the License at
8    *
9    *     http://www.apache.org/licenses/LICENSE-2.0
10   *
11   *  Unless required by applicable law or agreed to in writing, software
12   *  distributed under the License is distributed on an "AS IS" BASIS,
13   *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14   *  See the License for the specific language governing permissions and
15   *  limitations under the License.
16   */
17  package org.apache.geronimo.kernel.config;
18  
19  import java.util.LinkedHashSet;
20  import java.util.Iterator;
21  import java.util.Set;
22  
23  import org.apache.geronimo.kernel.repository.Artifact;
24  
25  /**
26   * @version $Rev: 410741 $ $Date: 2006-05-31 21:35:48 -0700 (Wed, 31 May 2006) $
27   */
28  public class ConfigurationStatus {
29      private Artifact configurationId;
30      private final Set loadParents = new LinkedHashSet();
31      private final Set startParents = new LinkedHashSet();
32      private final LinkedHashSet loadChildren = new LinkedHashSet();
33      private final LinkedHashSet startChildren = new LinkedHashSet();
34      private boolean loaded = false;
35      private boolean started = false;
36      private boolean userLoaded = false;
37      private boolean userStarted = false;
38  
39      public ConfigurationStatus(Artifact configId, Set loadParents, Set startParents) {
40          if (configId == null) throw new NullPointerException("configId is null");
41          if (loadParents == null) throw new NullPointerException("loadParents is null");
42          if (startParents == null) throw new NullPointerException("startParents is null");
43          if (!loadParents.containsAll(startParents)) {
44              throw new IllegalArgumentException("loadParents must contain all startParents");
45          }
46          this.configurationId = configId;
47          this.loadParents.addAll(loadParents);
48          this.startParents.addAll(startParents);
49  
50          for (Iterator iterator = loadParents.iterator(); iterator.hasNext();) {
51              ConfigurationStatus loadParent = (ConfigurationStatus) iterator.next();
52              loadParent.loadChildren.add(this);
53          }
54  
55          for (Iterator iterator = startParents.iterator(); iterator.hasNext();) {
56              ConfigurationStatus startParent = (ConfigurationStatus) iterator.next();
57              startParent.startChildren.add(this);
58          }
59      }
60  
61      public void destroy() {
62          if (started) {
63              throw new IllegalStateException("Configuration " + configurationId + " is still running");
64          }
65          if (loaded) {
66              throw new IllegalStateException("Configuration " + configurationId + " is still loaded");
67          }
68          if (loadChildren.size() > 0 || startChildren.size() > 0) {
69              throw new IllegalStateException("Configuration " + configurationId + " still has children");
70          }
71  
72          for (Iterator iterator = loadParents.iterator(); iterator.hasNext();) {
73              ConfigurationStatus loadParent = (ConfigurationStatus) iterator.next();
74              loadParent.loadChildren.remove(this);
75          }
76          loadParents.clear();
77  
78          for (Iterator iterator = startParents.iterator(); iterator.hasNext();) {
79              ConfigurationStatus startParent = (ConfigurationStatus) iterator.next();
80              startParent.startChildren.remove(this);
81          }
82          startChildren.clear();
83      }
84  
85      public Artifact getConfigurationId() {
86          return configurationId;
87      }
88  
89      public boolean isLoaded() {
90          return loaded;
91      }
92  
93      public boolean isStarted() {
94          return started;
95      }
96  
97      public boolean isUserLoaded() {
98          return userLoaded;
99      }
100 
101     public boolean isUserStarted() {
102         return userStarted;
103     }
104 
105 
106     public void upgrade(Artifact newId, Set newLoadParents, Set newStartParents) {
107         this.configurationId = newId;
108 
109         //
110         // remove links from the current parents to me
111         //
112         for (Iterator iterator = loadParents.iterator(); iterator.hasNext();) {
113             ConfigurationStatus loadParent = (ConfigurationStatus) iterator.next();
114             loadParent.loadChildren.remove(this);
115         }
116         loadParents.clear();
117 
118         for (Iterator iterator = startParents.iterator(); iterator.hasNext();) {
119             ConfigurationStatus startParent = (ConfigurationStatus) iterator.next();
120             startParent.startChildren.remove(this);
121         }
122         startChildren.clear();
123 
124         //
125         // connect to to the new parents
126         //
127         this.loadParents.addAll(newLoadParents);
128         this.startParents.addAll(newStartParents);
129 
130         for (Iterator iterator = loadParents.iterator(); iterator.hasNext();) {
131             ConfigurationStatus loadParent = (ConfigurationStatus) iterator.next();
132             loadParent.loadChildren.add(this);
133         }
134 
135         for (Iterator iterator = startParents.iterator(); iterator.hasNext();) {
136             ConfigurationStatus startParent = (ConfigurationStatus) iterator.next();
137             startParent.startChildren.add(this);
138         }
139     }
140 
141     public LinkedHashSet load() {
142         LinkedHashSet loadList = new LinkedHashSet();
143         loadInternal(loadList);
144         userLoaded = true;
145         return loadList;
146     }
147 
148     private void loadInternal(LinkedHashSet loadList) {
149         // visit all unloaded parents
150         for (Iterator iterator = loadParents.iterator(); iterator.hasNext();) {
151             ConfigurationStatus parent = (ConfigurationStatus) iterator.next();
152             if (!parent.isLoaded()) {
153                 parent.loadInternal(loadList);
154             }
155         }
156 
157         if (!loaded) {
158             loadList.add(configurationId);
159             loaded = true;
160         }
161     }
162 
163 
164     public LinkedHashSet start() {
165         if (!loaded) {
166             throw new IllegalStateException(configurationId + " is not loaded");
167         }
168         LinkedHashSet startList = new LinkedHashSet();
169         startInternal(startList);
170         userLoaded = true;
171         userStarted = true;
172         return startList;
173     }
174 
175     private void startInternal(LinkedHashSet startList) {
176         // visit all stopped parents
177         for (Iterator iterator = startParents.iterator(); iterator.hasNext();) {
178             ConfigurationStatus parent = (ConfigurationStatus) iterator.next();
179             if (!parent.isStarted()) {
180                 parent.startInternal(startList);
181             }
182         }
183 
184         if (!started) {
185             startList.add(configurationId);
186             started = true;
187         }
188     }
189 
190     /**
191      * Stop this configuration and its children (if it's running) or do nothing
192      * (if it's not running).
193      */
194     public LinkedHashSet stop(boolean gc) {
195         LinkedHashSet stopStatuses = new LinkedHashSet();
196         stopInternal(stopStatuses, gc);
197 
198         LinkedHashSet stopIds = new LinkedHashSet(stopStatuses.size());
199         for (Iterator iterator = stopStatuses.iterator(); iterator.hasNext();) {
200             ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator.next();
201             stopIds.add(configurationStatus.configurationId);
202         }
203 
204         return stopIds;
205     }
206 
207     private void stopInternal(LinkedHashSet stopList, boolean gc) {
208         // if we aren't started, there is nothing to do
209         if (!started) {
210             return;
211         }
212 
213         // visit all children
214         for (Iterator iterator = startChildren.iterator(); iterator.hasNext();) {
215             ConfigurationStatus child = (ConfigurationStatus) iterator.next();
216             if (child.isStarted()) {
217                 child.stopInternal(stopList, gc);
218             }
219         }
220 
221         // mark this node as stoped, and add this node to the stop list
222         if (started) {
223             started = false;
224             userStarted = false;
225             stopList.add(this);
226 
227             // if we are garbage collecting, visit parents
228             if (gc) {
229                 // visit all non-user started parents that haven't already been visited
230                 for (Iterator iterator = startParents.iterator(); iterator.hasNext();) {
231                     ConfigurationStatus parent = (ConfigurationStatus) iterator.next();
232                     if (!parent.isUserStarted() && stopList.containsAll(parent.startChildren)) {
233                         parent.stopInternal(stopList, gc);
234                     }
235                 }
236             }
237         }
238     }
239 
240     public LinkedHashSet restart() {
241         if (!started) {
242             throw new IllegalStateException(configurationId + " is not started");
243         }
244 
245         LinkedHashSet restartStatuses = new LinkedHashSet();
246         restartInternal(restartStatuses);
247 
248         LinkedHashSet restartIds = new LinkedHashSet(restartStatuses.size());
249         for (Iterator iterator = restartStatuses.iterator(); iterator.hasNext();) {
250             ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator.next();
251             restartIds.add(configurationStatus.configurationId);
252         }
253 
254         userLoaded = true;
255         userStarted = true;
256         return restartIds;
257     }
258 
259     private void restartInternal(LinkedHashSet restartList) {
260         // if we aren't started, there is nothing to do
261         if (!started) {
262             return;
263         }
264 
265         // visit all children
266         for (Iterator iterator = startChildren.iterator(); iterator.hasNext();) {
267             ConfigurationStatus child = (ConfigurationStatus) iterator.next();
268             if (child.isStarted()) {
269                 child.restartInternal(restartList);
270             }
271         }
272 
273         // add this node to the restart list
274         restartList.add(this);
275     }
276 
277     /**
278      * Unload the configuration and all its children (if it's loaded), or do
279      * nothing (if it's not loaded).
280      */
281     public LinkedHashSet unload(boolean gc) {
282 
283         LinkedHashSet unloadStatuses = new LinkedHashSet();
284         unloadInternal(unloadStatuses, gc);
285 
286         LinkedHashSet unloadIds = new LinkedHashSet(unloadStatuses.size());
287         for (Iterator iterator = unloadStatuses.iterator(); iterator.hasNext();) {
288             ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator.next();
289             unloadIds.add(configurationStatus.configurationId);
290         }
291 
292         return unloadIds;
293     }
294 
295     private void unloadInternal(LinkedHashSet unloadList, boolean gc) {
296         // if we aren't loaded, there is nothing to do
297         if (!loaded) {
298             return;
299         }
300 
301         // visit all loaded children
302         for (Iterator iterator = loadChildren.iterator(); iterator.hasNext();) {
303             ConfigurationStatus child = (ConfigurationStatus) iterator.next();
304             if (child.isLoaded()) {
305                 child.unloadInternal(unloadList, gc);
306             }
307         }
308 
309         // mark this node as unloaded, and add this node to the unload list
310         if (loaded) {
311             started = false;
312             userStarted = false;
313             loaded = false;
314             userLoaded = false;
315             unloadList.add(this);
316 
317             // if we are garbage collecting, visit parents
318             if (gc) {
319                 // visit all non-user loaded parents
320                 for (Iterator iterator = loadParents.iterator(); iterator.hasNext();) {
321                     ConfigurationStatus parent = (ConfigurationStatus) iterator.next();
322                     if (!parent.isUserLoaded() && unloadList.containsAll(parent.loadChildren)) {
323                         parent.unloadInternal(unloadList, gc);
324                     }
325                 }
326             }
327         }
328     }
329 
330     public LinkedHashSet reload() {
331         if (!loaded) {
332             throw new IllegalStateException(configurationId + " is not loaded");
333         }
334 
335         LinkedHashSet reloadStatuses = new LinkedHashSet();
336         reloadInternal(reloadStatuses);
337 
338         LinkedHashSet reloadIds = new LinkedHashSet(reloadStatuses.size());
339         for (Iterator iterator = reloadStatuses.iterator(); iterator.hasNext();) {
340             ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator.next();
341             reloadIds.add(configurationStatus.configurationId);
342         }
343 
344         userLoaded = true;
345         return reloadIds;
346     }
347 
348     private void reloadInternal(LinkedHashSet reloadList) {
349         // if we aren't loaded, there is nothing to do
350         if (!loaded) {
351             return;
352         }
353 
354         // visit all children
355         for (Iterator iterator = loadChildren.iterator(); iterator.hasNext();) {
356             ConfigurationStatus child = (ConfigurationStatus) iterator.next();
357             if (child.isLoaded()) {
358                 child.reloadInternal(reloadList);
359             }
360         }
361 
362         // add this node to the reload list
363         reloadList.add(this);
364     }
365 
366     public String toString() {
367         String load;
368         if (userLoaded) {
369             load = "user-loaded";
370         } else if (loaded) {
371             load = "loaded";
372         } else {
373             load = "not-loaded";
374         }
375         String start;
376         if (userLoaded) {
377             start = "user-started";
378         } else if (loaded) {
379             start = "started";
380         } else {
381             start = "not-started";
382         }
383         return "[" + configurationId + " " + load + " " + start + "]";
384     }
385 }