001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. You may obtain a copy of the License at
008: *
009: * http://www.apache.org/licenses/LICENSE-2.0
010: *
011: * Unless required by applicable law or agreed to in writing, software
012: * distributed under the License is distributed on an "AS IS" BASIS,
013: * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014: * See the License for the specific language governing permissions and
015: * limitations under the License.
016: */package org.apache.geronimo.kernel.config;
017:
018: import java.util.LinkedHashSet;
019: import java.util.Iterator;
020: import java.util.Set;
021:
022: import org.apache.geronimo.kernel.repository.Artifact;
023:
024: /**
025: * @version $Rev: 476049 $ $Date: 2006-11-16 20:35:17 -0800 (Thu, 16 Nov 2006) $
026: */
027: public class ConfigurationStatus {
028: private Artifact configurationId;
029: private final Set loadParents = new LinkedHashSet();
030: private final Set startParents = new LinkedHashSet();
031: private final LinkedHashSet loadChildren = new LinkedHashSet();
032: private final LinkedHashSet startChildren = new LinkedHashSet();
033: private boolean loaded = false;
034: private boolean started = false;
035: private boolean userLoaded = false;
036: private boolean userStarted = false;
037:
038: public ConfigurationStatus(Artifact configId, Set loadParents,
039: Set startParents) {
040: if (configId == null)
041: throw new NullPointerException("configId is null");
042: if (loadParents == null)
043: throw new NullPointerException("loadParents is null");
044: if (startParents == null)
045: throw new NullPointerException("startParents is null");
046: if (!loadParents.containsAll(startParents)) {
047: throw new IllegalArgumentException(
048: "loadParents must contain all startParents");
049: }
050: this .configurationId = configId;
051: this .loadParents.addAll(loadParents);
052: this .startParents.addAll(startParents);
053:
054: for (Iterator iterator = loadParents.iterator(); iterator
055: .hasNext();) {
056: ConfigurationStatus loadParent = (ConfigurationStatus) iterator
057: .next();
058: loadParent.loadChildren.add(this );
059: }
060:
061: for (Iterator iterator = startParents.iterator(); iterator
062: .hasNext();) {
063: ConfigurationStatus startParent = (ConfigurationStatus) iterator
064: .next();
065: startParent.startChildren.add(this );
066: }
067: }
068:
069: public void destroy() {
070: if (started) {
071: throw new IllegalStateException("Configuration "
072: + configurationId + " is still running");
073: }
074: if (loaded) {
075: throw new IllegalStateException("Configuration "
076: + configurationId + " is still loaded");
077: }
078: if (loadChildren.size() > 0 || startChildren.size() > 0) {
079: throw new IllegalStateException("Configuration "
080: + configurationId + " still has children");
081: }
082:
083: for (Iterator iterator = loadParents.iterator(); iterator
084: .hasNext();) {
085: ConfigurationStatus loadParent = (ConfigurationStatus) iterator
086: .next();
087: loadParent.loadChildren.remove(this );
088: }
089: loadParents.clear();
090:
091: for (Iterator iterator = startParents.iterator(); iterator
092: .hasNext();) {
093: ConfigurationStatus startParent = (ConfigurationStatus) iterator
094: .next();
095: startParent.startChildren.remove(this );
096: }
097: startChildren.clear();
098: }
099:
100: public Artifact getConfigurationId() {
101: return configurationId;
102: }
103:
104: public boolean isLoaded() {
105: return loaded;
106: }
107:
108: public boolean isStarted() {
109: return started;
110: }
111:
112: public boolean isUserLoaded() {
113: return userLoaded;
114: }
115:
116: public boolean isUserStarted() {
117: return userStarted;
118: }
119:
120: public void upgrade(Artifact newId, Set newLoadParents,
121: Set newStartParents) {
122: this .configurationId = newId;
123:
124: //
125: // remove links from the current parents to me
126: //
127: for (Iterator iterator = loadParents.iterator(); iterator
128: .hasNext();) {
129: ConfigurationStatus loadParent = (ConfigurationStatus) iterator
130: .next();
131: loadParent.loadChildren.remove(this );
132: }
133: loadParents.clear();
134:
135: for (Iterator iterator = startParents.iterator(); iterator
136: .hasNext();) {
137: ConfigurationStatus startParent = (ConfigurationStatus) iterator
138: .next();
139: startParent.startChildren.remove(this );
140: }
141: startChildren.clear();
142:
143: //
144: // connect to to the new parents
145: //
146: this .loadParents.addAll(newLoadParents);
147: this .startParents.addAll(newStartParents);
148:
149: for (Iterator iterator = loadParents.iterator(); iterator
150: .hasNext();) {
151: ConfigurationStatus loadParent = (ConfigurationStatus) iterator
152: .next();
153: loadParent.loadChildren.add(this );
154: }
155:
156: for (Iterator iterator = startParents.iterator(); iterator
157: .hasNext();) {
158: ConfigurationStatus startParent = (ConfigurationStatus) iterator
159: .next();
160: startParent.startChildren.add(this );
161: }
162: }
163:
164: public LinkedHashSet load() {
165: LinkedHashSet loadList = new LinkedHashSet();
166: loadInternal(loadList);
167: userLoaded = true;
168: return loadList;
169: }
170:
171: private void loadInternal(LinkedHashSet loadList) {
172: // visit all unloaded parents
173: for (Iterator iterator = loadParents.iterator(); iterator
174: .hasNext();) {
175: ConfigurationStatus parent = (ConfigurationStatus) iterator
176: .next();
177: if (!parent.isLoaded()) {
178: parent.loadInternal(loadList);
179: }
180: }
181:
182: if (!loaded) {
183: loadList.add(configurationId);
184: loaded = true;
185: }
186: }
187:
188: public LinkedHashSet start() {
189: if (!loaded) {
190: throw new IllegalStateException(configurationId
191: + " is not loaded");
192: }
193: LinkedHashSet startList = new LinkedHashSet();
194: startInternal(startList);
195: userLoaded = true;
196: userStarted = true;
197: return startList;
198: }
199:
200: private void startInternal(LinkedHashSet startList) {
201: // visit all stopped parents
202: for (Iterator iterator = startParents.iterator(); iterator
203: .hasNext();) {
204: ConfigurationStatus parent = (ConfigurationStatus) iterator
205: .next();
206: if (!parent.isStarted()) {
207: parent.startInternal(startList);
208: }
209: }
210:
211: if (!started) {
212: startList.add(configurationId);
213: started = true;
214: }
215: }
216:
217: /**
218: * Stop this configuration and its children (if it's running) or do nothing
219: * (if it's not running).
220: */
221: public LinkedHashSet stop(boolean gc) {
222: LinkedHashSet stopStatuses = new LinkedHashSet();
223: stopInternal(stopStatuses, gc);
224:
225: LinkedHashSet stopIds = new LinkedHashSet(stopStatuses.size());
226: for (Iterator iterator = stopStatuses.iterator(); iterator
227: .hasNext();) {
228: ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator
229: .next();
230: stopIds.add(configurationStatus.configurationId);
231: }
232:
233: return stopIds;
234: }
235:
236: private void stopInternal(LinkedHashSet stopList, boolean gc) {
237: // if we aren't started, there is nothing to do
238: if (!started) {
239: return;
240: }
241:
242: // visit all children
243: for (Iterator iterator = startChildren.iterator(); iterator
244: .hasNext();) {
245: ConfigurationStatus child = (ConfigurationStatus) iterator
246: .next();
247: if (child.isStarted()) {
248: child.stopInternal(stopList, gc);
249: }
250: }
251:
252: // mark this node as stoped, and add this node to the stop list
253: if (started) {
254: started = false;
255: userStarted = false;
256: stopList.add(this );
257:
258: // if we are garbage collecting, visit parents
259: if (gc) {
260: // visit all non-user started parents that haven't already been visited
261: for (Iterator iterator = startParents.iterator(); iterator
262: .hasNext();) {
263: ConfigurationStatus parent = (ConfigurationStatus) iterator
264: .next();
265: if (!parent.isUserStarted()
266: && stopList
267: .containsAll(parent.startChildren)) {
268: parent.stopInternal(stopList, gc);
269: }
270: }
271: }
272: }
273: }
274:
275: public LinkedHashSet restart() {
276: if (!started) {
277: throw new IllegalStateException(configurationId
278: + " is not started");
279: }
280:
281: LinkedHashSet restartStatuses = new LinkedHashSet();
282: restartInternal(restartStatuses);
283:
284: LinkedHashSet restartIds = new LinkedHashSet(restartStatuses
285: .size());
286: for (Iterator iterator = restartStatuses.iterator(); iterator
287: .hasNext();) {
288: ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator
289: .next();
290: restartIds.add(configurationStatus.configurationId);
291: }
292:
293: userLoaded = true;
294: userStarted = true;
295: return restartIds;
296: }
297:
298: private void restartInternal(LinkedHashSet restartList) {
299: // if we aren't started, there is nothing to do
300: if (!started) {
301: return;
302: }
303:
304: // visit all children
305: for (Iterator iterator = startChildren.iterator(); iterator
306: .hasNext();) {
307: ConfigurationStatus child = (ConfigurationStatus) iterator
308: .next();
309: if (child.isStarted()) {
310: child.restartInternal(restartList);
311: }
312: }
313:
314: // add this node to the restart list
315: restartList.add(this );
316: }
317:
318: /**
319: * Unload the configuration and all its children (if it's loaded), or do
320: * nothing (if it's not loaded).
321: */
322: public LinkedHashSet unload(boolean gc) {
323:
324: LinkedHashSet unloadStatuses = new LinkedHashSet();
325: unloadInternal(unloadStatuses, gc);
326:
327: LinkedHashSet unloadIds = new LinkedHashSet(unloadStatuses
328: .size());
329: for (Iterator iterator = unloadStatuses.iterator(); iterator
330: .hasNext();) {
331: ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator
332: .next();
333: unloadIds.add(configurationStatus.configurationId);
334: }
335:
336: return unloadIds;
337: }
338:
339: private void unloadInternal(LinkedHashSet unloadList, boolean gc) {
340: // if we aren't loaded, there is nothing to do
341: if (!loaded) {
342: return;
343: }
344:
345: // visit all loaded children
346: for (Iterator iterator = loadChildren.iterator(); iterator
347: .hasNext();) {
348: ConfigurationStatus child = (ConfigurationStatus) iterator
349: .next();
350: if (child.isLoaded()) {
351: child.unloadInternal(unloadList, gc);
352: }
353: }
354:
355: // mark this node as unloaded, and add this node to the unload list
356: if (loaded) {
357: started = false;
358: userStarted = false;
359: loaded = false;
360: userLoaded = false;
361: unloadList.add(this );
362:
363: // if we are garbage collecting, visit parents
364: if (gc) {
365: // visit all non-user loaded parents
366: for (Iterator iterator = loadParents.iterator(); iterator
367: .hasNext();) {
368: ConfigurationStatus parent = (ConfigurationStatus) iterator
369: .next();
370: if (!parent.isUserLoaded()
371: && unloadList
372: .containsAll(parent.loadChildren)) {
373: parent.unloadInternal(unloadList, gc);
374: }
375: }
376: }
377: }
378: }
379:
380: public LinkedHashSet reload() {
381: if (!loaded) {
382: throw new IllegalStateException(configurationId
383: + " is not loaded");
384: }
385:
386: LinkedHashSet reloadStatuses = new LinkedHashSet();
387: reloadInternal(reloadStatuses);
388:
389: LinkedHashSet reloadIds = new LinkedHashSet(reloadStatuses
390: .size());
391: for (Iterator iterator = reloadStatuses.iterator(); iterator
392: .hasNext();) {
393: ConfigurationStatus configurationStatus = (ConfigurationStatus) iterator
394: .next();
395: reloadIds.add(configurationStatus.configurationId);
396: }
397:
398: userLoaded = true;
399: return reloadIds;
400: }
401:
402: private void reloadInternal(LinkedHashSet reloadList) {
403: // if we aren't loaded, there is nothing to do
404: if (!loaded) {
405: return;
406: }
407:
408: // visit all children
409: for (Iterator iterator = loadChildren.iterator(); iterator
410: .hasNext();) {
411: ConfigurationStatus child = (ConfigurationStatus) iterator
412: .next();
413: if (child.isLoaded()) {
414: child.reloadInternal(reloadList);
415: }
416: }
417:
418: // add this node to the reload list
419: reloadList.add(this );
420: }
421:
422: public String toString() {
423: String load;
424: if (userLoaded) {
425: load = "user-loaded";
426: } else if (loaded) {
427: load = "loaded";
428: } else {
429: load = "not-loaded";
430: }
431: String start;
432: if (userLoaded) {
433: start = "user-started";
434: } else if (loaded) {
435: start = "started";
436: } else {
437: start = "not-started";
438: }
439: return "[" + configurationId + " " + load + " " + start + "]";
440: }
441: }
|