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 */
017 package org.apache.geronimo.kernel.config;
018
019 import java.io.IOException;
020 import java.util.ArrayList;
021 import java.util.Collection;
022 import java.util.Collections;
023 import java.util.HashSet;
024 import java.util.Iterator;
025 import java.util.LinkedHashMap;
026 import java.util.LinkedHashSet;
027 import java.util.List;
028 import java.util.ListIterator;
029 import java.util.Map;
030 import java.util.Set;
031
032 import org.apache.commons.logging.Log;
033 import org.apache.commons.logging.LogFactory;
034 import org.apache.geronimo.gbean.AbstractName;
035 import org.apache.geronimo.gbean.GBeanInfo;
036 import org.apache.geronimo.gbean.GBeanInfoBuilder;
037 import org.apache.geronimo.kernel.management.State;
038 import org.apache.geronimo.kernel.repository.Artifact;
039 import org.apache.geronimo.kernel.repository.ArtifactResolver;
040 import org.apache.geronimo.kernel.repository.Dependency;
041 import org.apache.geronimo.kernel.repository.Environment;
042 import org.apache.geronimo.kernel.repository.ImportType;
043 import org.apache.geronimo.kernel.repository.MissingDependencyException;
044 import org.apache.geronimo.kernel.repository.Repository;
045 import org.apache.geronimo.kernel.repository.Version;
046
047 /**
048 * @version $Rev: 557026 $ $Date: 2007-07-17 14:56:15 -0400 (Tue, 17 Jul 2007) $
049 */
050 public class SimpleConfigurationManager implements ConfigurationManager {
051 protected static final Log log = LogFactory.getLog(SimpleConfigurationManager.class);
052 protected final Collection stores;
053 private final ArtifactResolver artifactResolver;
054 protected final Map configurations = new LinkedHashMap();
055 protected final ConfigurationModel configurationModel = new ConfigurationModel();
056 protected final Collection repositories;
057 protected final Collection watchers;
058
059 /**
060 * When this is not null, it points to the "new" configuration that is
061 * part of an in-process reload operation. This configuration will
062 * definitely be loaded, but might not be started yet. It shold never be
063 * populated outside the scope of a reload operation.
064 */
065 private Configuration reloadingConfiguration;
066
067
068 public SimpleConfigurationManager(Collection stores, ArtifactResolver artifactResolver, Collection repositories) {
069 this(stores, artifactResolver, repositories, Collections.EMPTY_SET);
070 }
071
072 public SimpleConfigurationManager(Collection stores, ArtifactResolver artifactResolver, Collection repositories, Collection watchers) {
073 if (stores == null) stores = Collections.EMPTY_SET;
074 if (repositories == null) repositories = Collections.EMPTY_SET;
075 if (watchers == null) watchers = Collections.EMPTY_SET;
076
077 this.stores = stores;
078 this.artifactResolver = artifactResolver;
079 this.repositories = repositories;
080 this.watchers = watchers;
081 }
082
083 public synchronized boolean isInstalled(Artifact configId) {
084 if(!configId.isResolved()) {
085 throw new IllegalArgumentException("Artifact "+configId+" is not fully resolved");
086 }
087 List storeSnapshot = getStoreList();
088 for (int i = 0; i < storeSnapshot.size(); i++) {
089 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
090 if(store.containsConfiguration(configId)) {
091 return true;
092 }
093 }
094 return false;
095 }
096
097 public synchronized boolean isLoaded(Artifact configId) {
098 if(!configId.isResolved()) {
099 throw new IllegalArgumentException("Artifact "+configId+" is not fully resolved");
100 }
101 if(reloadingConfiguration != null && reloadingConfiguration.getId().equals(configId)) {
102 return true;
103 }
104 return configurationModel.isLoaded(configId);
105 }
106
107 public synchronized boolean isRunning(Artifact configId) {
108 if(!configId.isResolved()) {
109 throw new IllegalArgumentException("Artifact "+configId+" is not fully resolved");
110 }
111 return configurationModel.isStarted(configId);
112 }
113
114 public Artifact[] getInstalled(Artifact query) {
115 Artifact[] all = artifactResolver.queryArtifacts(query);
116 List configs = new ArrayList();
117 for (int i = 0; i < all.length; i++) {
118 Artifact artifact = all[i];
119 if(isConfiguration(artifact)) {
120 configs.add(artifact);
121 }
122 }
123 if(configs.size() == all.length) {
124 return all;
125 }
126 return (Artifact[]) configs.toArray(new Artifact[configs.size()]);
127 }
128
129 public Artifact[] getLoaded(Artifact query) {
130 return configurationModel.getLoaded(query);
131 }
132
133 public Artifact[] getRunning(Artifact query) {
134 return configurationModel.getStarted(query);
135 }
136
137
138 public List listStores() {
139 List storeSnapshot = getStoreList();
140 List result = new ArrayList(storeSnapshot.size());
141 for (int i = 0; i < storeSnapshot.size(); i++) {
142 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
143 result.add(store.getAbstractName());
144 }
145 return result;
146 }
147
148 public ConfigurationStore[] getStores() {
149 List storeSnapshot = getStoreList();
150 return (ConfigurationStore[]) storeSnapshot.toArray(new ConfigurationStore[storeSnapshot.size()]);
151 }
152
153 public Collection getRepositories() {
154 return repositories;
155 }
156
157 public List listConfigurations() {
158 List storeSnapshot = getStoreList();
159 List list = new ArrayList();
160 for (int i = 0; i < storeSnapshot.size(); i++) {
161 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
162 list.addAll(listConfigurations(store));
163 }
164 return list;
165 }
166
167 public ConfigurationStore getStoreForConfiguration(Artifact configId) {
168 if(!configId.isResolved()) {
169 throw new IllegalArgumentException("Artifact "+configId+" is not fully resolved");
170 }
171 List storeSnapshot = getStoreList();
172 for (int i = 0; i < storeSnapshot.size(); i++) {
173 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
174 if(store.containsConfiguration(configId)) {
175 return store;
176 }
177 }
178 return null;
179 }
180
181 public List listConfigurations(AbstractName storeName) throws NoSuchStoreException {
182 List storeSnapshot = getStoreList();
183 for (int i = 0; i < storeSnapshot.size(); i++) {
184 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
185 if (storeName.equals(store.getAbstractName())) {
186 return listConfigurations(store);
187 }
188 }
189 throw new NoSuchStoreException("No such store: " + storeName);
190 }
191
192 private List listConfigurations(ConfigurationStore store) {
193 List list = store.listConfigurations();
194 for (ListIterator iterator = list.listIterator(); iterator.hasNext();) {
195 ConfigurationInfo configurationInfo = (ConfigurationInfo) iterator.next();
196 if (isRunning(configurationInfo.getConfigID())) {
197 configurationInfo = new ConfigurationInfo(store.getAbstractName(),
198 configurationInfo.getConfigID(),
199 configurationInfo.getType(),
200 configurationInfo.getCreated(),
201 configurationInfo.getOwnedConfigurations(),
202 configurationInfo.getChildConfigurations(),
203 configurationInfo.getInPlaceLocation(),
204 State.RUNNING);
205 } else {
206 configurationInfo = new ConfigurationInfo(store.getAbstractName(),
207 configurationInfo.getConfigID(),
208 configurationInfo.getType(),
209 configurationInfo.getCreated(),
210 configurationInfo.getOwnedConfigurations(),
211 configurationInfo.getChildConfigurations(),
212 configurationInfo.getInPlaceLocation(),
213 State.STOPPED);
214 }
215 iterator.set(configurationInfo);
216 }
217 return list;
218 }
219
220 public boolean isConfiguration(Artifact artifact) {
221 if(!artifact.isResolved()) {
222 throw new IllegalArgumentException("Artifact "+artifact+" is not fully resolved");
223 }
224 synchronized (this) {
225 // if it is loaded, it is definitely a configuration
226 if (configurations.containsKey(artifact)) {
227 return true;
228 }
229 }
230
231 // see if any stores think it is a configuration
232 List storeSnapshot = getStoreList();
233 for (int i = 0; i < storeSnapshot.size(); i++) {
234 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
235 if (store.containsConfiguration(artifact)) {
236 return true;
237 }
238 }
239 return false;
240 }
241
242 public synchronized Configuration getConfiguration(Artifact configurationId) {
243 if(!configurationId.isResolved()) {
244 throw new IllegalArgumentException("Artifact "+configurationId+" is not fully resolved");
245 }
246 if(reloadingConfiguration != null && reloadingConfiguration.getId().equals(configurationId)) {
247 return reloadingConfiguration;
248 }
249 return (Configuration) configurations.get(configurationId);
250 }
251
252 public synchronized LifecycleResults loadConfiguration(Artifact configurationId) throws NoSuchConfigException, LifecycleException {
253 return loadConfiguration(configurationId, NullLifecycleMonitor.INSTANCE);
254 }
255
256 public synchronized LifecycleResults loadConfiguration(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
257 if(!configurationId.isResolved()) {
258 throw new IllegalArgumentException("Artifact "+configurationId+" is not fully resolved");
259 }
260 if (isLoaded(configurationId)) {
261 // already loaded, so just mark the configuration as user loaded
262 load(configurationId);
263
264 monitor.finished();
265 return new LifecycleResults();
266 }
267
268 // load the ConfigurationData for the new configuration
269 ConfigurationData configurationData = null;
270 try {
271 configurationData = loadConfigurationData(configurationId, monitor);
272 } catch (Exception e) {
273 monitor.finished();
274 throw new LifecycleException("load", configurationId, e);
275 }
276
277 // load the configuration
278 LifecycleResults results = loadConfiguration(configurationData, monitor);
279
280 return results;
281 }
282
283 public synchronized LifecycleResults loadConfiguration(ConfigurationData configurationData) throws NoSuchConfigException, LifecycleException {
284 return loadConfiguration(configurationData, NullLifecycleMonitor.INSTANCE);
285 }
286
287 public synchronized LifecycleResults loadConfiguration(ConfigurationData configurationData, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
288 Artifact id = configurationData.getId();
289 LifecycleResults results = new LifecycleResults();
290 if (!isLoaded(id)) {
291 // recursively load configurations from the new child to the parents
292 LinkedHashMap configurationsToLoad = new LinkedHashMap();
293 try {
294 loadDepthFirst(configurationData, configurationsToLoad, monitor);
295 } catch (Exception e) {
296 monitor.finished();
297 throw new LifecycleException("load", id, e);
298 }
299
300 // load and start the unloaded the gbean for each configuration (depth first)
301 Map actuallyLoaded = new LinkedHashMap(configurationsToLoad.size());
302 Artifact configurationId = null;
303 try {
304 for (Iterator iterator = configurationsToLoad.entrySet().iterator(); iterator.hasNext();) {
305 Map.Entry entry = (Map.Entry) iterator.next();
306 configurationId = (Artifact) entry.getKey();
307 UnloadedConfiguration unloadedConfiguration = (UnloadedConfiguration) entry.getValue();
308
309 monitor.loading(configurationId);
310 Configuration configuration = load(unloadedConfiguration.getConfigurationData(), unloadedConfiguration.getResolvedParentIds(), actuallyLoaded);
311 monitor.succeeded(configurationId);
312
313 actuallyLoaded.put(configurationId, configuration);
314 }
315 } catch (Exception e) {
316 monitor.failed(configurationId, e);
317
318 // there was a problem, so we need to unload all configurations that were actually loaded
319 for (Iterator iterator = actuallyLoaded.values().iterator(); iterator.hasNext();) {
320 Configuration configuration = (Configuration) iterator.next();
321 unload(configuration);
322 }
323
324 monitor.finished();
325 throw new LifecycleException("load", id, e);
326 }
327
328 // update the status of the loaded configurations
329 addNewConfigurationsToModel(actuallyLoaded);
330 results.setLoaded(actuallyLoaded.keySet());
331 }
332 load(id);
333 monitor.finished();
334 return results;
335 }
336
337 protected void load(Artifact configurationId) throws NoSuchConfigException {
338 configurationModel.load(configurationId);
339 }
340
341 protected Configuration load(ConfigurationData configurationData, LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException {
342 Artifact configurationId = configurationData.getId();
343 try {
344 Collection parents = findParentConfigurations(resolvedParentIds, loadedConfigurations);
345
346 Configuration configuration = new Configuration(parents, configurationData, new ConfigurationResolver(configurationData, repositories, artifactResolver), null);
347 configuration.doStart();
348 return configuration;
349 } catch (Exception e) {
350 throw new InvalidConfigException("Error starting configuration gbean " + configurationId, e);
351 }
352 }
353
354 private Collection findParentConfigurations(LinkedHashSet resolvedParentIds, Map loadedConfigurations) throws InvalidConfigException {
355 LinkedHashMap parents = new LinkedHashMap();
356 for (Iterator iterator = resolvedParentIds.iterator(); iterator.hasNext();) {
357 Artifact resolvedArtifact = (Artifact) iterator.next();
358
359 Configuration parent = null;
360 if (loadedConfigurations.containsKey(resolvedArtifact)) {
361 parent = (Configuration) loadedConfigurations.get(resolvedArtifact);
362 } else if (isLoaded(resolvedArtifact)) {
363 parent = getConfiguration(resolvedArtifact);
364 } else {
365 throw new InvalidConfigException("Cound not find parent configuration: " + resolvedArtifact);
366 }
367
368 parents.put(resolvedArtifact, parent);
369 }
370 return parents.values();
371 }
372
373 private void addNewConfigurationsToModel(Map loadedConfigurations) throws NoSuchConfigException {
374 for (Iterator iterator = loadedConfigurations.values().iterator(); iterator.hasNext();) {
375 Configuration configuration = (Configuration) iterator.next();
376 addNewConfigurationToModel(configuration);
377 }
378 }
379
380 protected void addNewConfigurationToModel(Configuration configuration) throws NoSuchConfigException {
381 configurationModel.addConfiguation(configuration.getId(),
382 getConfigurationIds(getLoadParents(configuration)),
383 getConfigurationIds(getStartParents(configuration)));
384 configurations.put(configuration.getId(), configuration);
385 }
386
387 protected LinkedHashSet getLoadParents(Configuration configuration) {
388 LinkedHashSet loadParent = new LinkedHashSet(configuration.getClassParents());
389 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) {
390 Configuration childConfiguration = (Configuration) iterator.next();
391 LinkedHashSet childLoadParent = getLoadParents(childConfiguration);
392
393 // remove this configuration from the parent Ids since it will cause an infinite loop
394 childLoadParent.remove(configuration);
395
396 loadParent.addAll(childLoadParent);
397 }
398 return loadParent;
399 }
400
401 protected LinkedHashSet getStartParents(Configuration configuration) {
402 LinkedHashSet startParent = new LinkedHashSet(configuration.getServiceParents());
403 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) {
404 Configuration childConfiguration = (Configuration) iterator.next();
405 LinkedHashSet childStartParent = getStartParents(childConfiguration);
406
407 // remove this configuration from the parent Ids since it will cause an infinite loop
408 childStartParent.remove(configuration);
409
410 startParent.addAll(childStartParent);
411 }
412 return startParent;
413 }
414
415 private static LinkedHashSet getConfigurationIds(Collection configurations) {
416 LinkedHashSet configurationIds = new LinkedHashSet(configurations.size());
417 for (Iterator iterator = configurations.iterator(); iterator.hasNext();) {
418 Configuration configuration = (Configuration) iterator.next();
419 configurationIds.add(configuration.getId());
420 }
421 return configurationIds;
422 }
423
424 private synchronized void loadDepthFirst(ConfigurationData configurationData, LinkedHashMap configurationsToLoad, LifecycleMonitor monitor) throws NoSuchConfigException, IOException, InvalidConfigException, MissingDependencyException {
425 // if this parent hasn't already been processed, iterate into the parent
426 Artifact configurationId = configurationData.getId();
427 if (!configurationsToLoad.containsKey(configurationId)) {
428 LinkedHashSet resolvedParentIds = resolveParentIds(configurationData);
429
430 for (Iterator iterator = resolvedParentIds.iterator(); iterator.hasNext();) {
431 Artifact parentId = (Artifact) iterator.next();
432 // if this parent id hasn't already been loaded and is actually a configuration
433 if (!isLoaded(parentId) && isConfiguration(parentId)) {
434 ConfigurationData parentConfigurationData = loadConfigurationData(parentId, monitor);
435 loadDepthFirst(parentConfigurationData, configurationsToLoad, monitor);
436 }
437 }
438
439 // depth first - all unloaded parents have been added, now add this configuration
440 configurationsToLoad.put(configurationId, new UnloadedConfiguration(configurationData, resolvedParentIds));
441 }
442 }
443
444 private ConfigurationData loadConfigurationData(Artifact configurationId, LifecycleMonitor monitor) throws NoSuchConfigException, IOException, InvalidConfigException {
445 List storeSnapshot = getStoreList();
446
447 monitor.addConfiguration(configurationId);
448 monitor.reading(configurationId);
449 for (int i = 0; i < storeSnapshot.size(); i++) {
450 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
451 if (store.containsConfiguration(configurationId)) {
452 ConfigurationData configurationData = store.loadConfiguration(configurationId);
453 monitor.succeeded(configurationId);
454 return configurationData;
455 }
456 }
457 NoSuchConfigException exception = new NoSuchConfigException(configurationId);
458 monitor.failed(configurationId, exception);
459 throw exception;
460 }
461
462 private LinkedHashSet<Artifact> resolveParentIds(ConfigurationData configurationData) throws MissingDependencyException, InvalidConfigException {
463 Environment environment = configurationData.getEnvironment();
464
465 LinkedHashSet<Artifact> parentIds = new LinkedHashSet<Artifact>();
466 List<Dependency> dependencies = new ArrayList<Dependency>(environment.getDependencies());
467 for (ListIterator<Dependency> iterator = dependencies.listIterator(); iterator.hasNext();) {
468 Dependency dependency = iterator.next();
469 Artifact resolvedArtifact = artifactResolver.resolveInClassLoader(dependency.getArtifact());
470 if (isConfiguration(resolvedArtifact)) {
471 parentIds.add(resolvedArtifact);
472
473 // update the dependency list to contain the resolved artifact
474 dependency = new Dependency(resolvedArtifact, dependency.getImportType());
475 iterator.set(dependency);
476 } else if (dependency.getImportType() == ImportType.SERVICES) {
477 // Service depdendencies require that the depdencency be a configuration
478 throw new InvalidConfigException("Dependency does not have services: " + resolvedArtifact);
479 }
480 }
481
482 for (Iterator iterator = configurationData.getChildConfigurations().values().iterator(); iterator.hasNext();) {
483 ConfigurationData childConfigurationData = (ConfigurationData) iterator.next();
484 LinkedHashSet<Artifact> childParentIds = resolveParentIds(childConfigurationData);
485 // remove this configuration's id from the parent Ids since it will cause an infinite loop
486 childParentIds.remove(configurationData.getId());
487 parentIds.addAll(childParentIds);
488 }
489 return parentIds;
490 }
491
492 private static class UnloadedConfiguration {
493 private final ConfigurationData configurationData;
494 private final LinkedHashSet resolvedParentIds;
495
496 public UnloadedConfiguration(ConfigurationData configurationData, LinkedHashSet resolvedParentIds) {
497 this.configurationData = configurationData;
498 this.resolvedParentIds = resolvedParentIds;
499 }
500
501 public ConfigurationData getConfigurationData() {
502 return configurationData;
503 }
504
505 public LinkedHashSet getResolvedParentIds() {
506 return resolvedParentIds;
507 }
508 }
509
510 public synchronized LifecycleResults startConfiguration(Artifact id) throws NoSuchConfigException, LifecycleException {
511 return startConfiguration(id, NullLifecycleMonitor.INSTANCE);
512 }
513
514 public synchronized LifecycleResults startConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
515 if(!id.isResolved()) {
516 throw new IllegalArgumentException("Artifact "+id+" is not fully resolved");
517 }
518 LinkedHashSet unstartedConfigurations = configurationModel.start(id);
519
520 addConfigurationsToMonitor(monitor, unstartedConfigurations);
521
522 LifecycleResults results = new LifecycleResults();
523 Artifact configurationId = null;
524 try {
525 for (Iterator iterator = unstartedConfigurations.iterator(); iterator.hasNext();) {
526 configurationId = (Artifact) iterator.next();
527 Configuration configuration = getConfiguration(configurationId);
528
529 monitor.starting(configurationId);
530 start(configuration);
531 monitor.succeeded(configurationId);
532
533 results.addStarted(configurationId);
534 }
535 } catch (Exception e) {
536 monitor.failed(configurationId, e);
537 configurationModel.stop(id);
538
539 for (Iterator iterator = results.getStarted().iterator(); iterator.hasNext();) {
540 configurationId = (Artifact) iterator.next();
541 Configuration configuration = getConfiguration(configurationId);
542 monitor.stopping(configurationId);
543 stop(configuration);
544 monitor.succeeded(configurationId);
545 }
546 monitor.finished();
547 throw new LifecycleException("start", id, e);
548 }
549 monitor.finished();
550 return results;
551 }
552
553 protected void start(Configuration configuration) throws Exception {
554 throw new UnsupportedOperationException();
555 }
556
557 public synchronized LifecycleResults stopConfiguration(Artifact id) throws NoSuchConfigException {
558 return stopConfiguration(id, NullLifecycleMonitor.INSTANCE);
559 }
560
561 public synchronized LifecycleResults stopConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException {
562 if(!id.isResolved()) {
563 throw new IllegalArgumentException("Artifact "+id+" is not fully resolved");
564 }
565 LinkedHashSet stopList = configurationModel.stop(id);
566
567 addConfigurationsToMonitor(monitor, stopList);
568
569 LifecycleResults results = new LifecycleResults();
570 for (Iterator iterator = stopList.iterator(); iterator.hasNext();) {
571 Artifact configurationId = (Artifact) iterator.next();
572 Configuration configuration = getConfiguration(configurationId);
573
574 monitor.stopping(configurationId);
575 stop(configuration);
576 monitor.succeeded(configurationId);
577
578 results.addStopped(configurationId);
579 }
580
581 monitor.finished();
582 return results;
583 }
584
585 protected void stop(Configuration configuration) {
586 // Don't throw an exception because we call this from unload to be sure that all
587 // unloaded configurations are stopped first
588 }
589
590 public synchronized LifecycleResults restartConfiguration(Artifact id) throws NoSuchConfigException, LifecycleException {
591 return restartConfiguration(id, NullLifecycleMonitor.INSTANCE);
592 }
593
594 public synchronized LifecycleResults restartConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
595 if(!id.isResolved()) {
596 throw new IllegalArgumentException("Artifact "+id+" is not fully resolved");
597 }
598 // get a sorted list of configurations to restart
599 LinkedHashSet restartList = configurationModel.restart(id);
600
601 addConfigurationsToMonitor(monitor, restartList);
602
603 // stop the configuations
604 LifecycleResults results = new LifecycleResults();
605 for (Iterator iterator = restartList.iterator(); iterator.hasNext();) {
606 Artifact configurationId = (Artifact) iterator.next();
607 Configuration configuration = getConfiguration(configurationId);
608 monitor.stopping(configurationId);
609 stop(configuration);
610 monitor.succeeded(configurationId);
611 results.addStopped(configurationId);
612 }
613
614 // reverse the list
615 restartList = reverse(restartList);
616
617 // restart the configurations
618 Set skip = new HashSet();
619 for (Iterator iterator = restartList.iterator(); iterator.hasNext();) {
620 Artifact configurationId = (Artifact) iterator.next();
621
622 // skip the configurations that have alredy failed or are children of failed configurations
623 if (skip.contains(configurationId)) {
624 continue;
625 }
626
627 // try to start the configuation
628 try {
629 Configuration configuration = getConfiguration(configurationId);
630 monitor.starting(configurationId);
631 start(configuration);
632 monitor.succeeded(configurationId);
633 results.addStarted(configurationId);
634 } catch (Exception e) {
635 // the configuraiton failed to restart
636 results.addFailed(configurationId, e);
637 monitor.failed(configurationId, e);
638 skip.add(configurationId);
639
640 // officially stop the configuration in the model (without gc)
641 LinkedHashSet stopList = configurationModel.stop(configurationId, false);
642
643 // all of the configurations to be stopped must be in our restart list, or the model is corrupt
644 if (!restartList.containsAll(stopList)) {
645 throw new AssertionError("Configuration data model is corrupt. You must restart your server.");
646 }
647
648 // add the children of the failed configuration to the results as stopped
649 for (Iterator iterator1 = stopList.iterator(); iterator1.hasNext();) {
650 Artifact failedId = (Artifact) iterator1.next();
651
652 // if any of the failed configuration is in the restarted set, the model is
653 // corrupt because we started a child before a parent
654 if (results.wasStarted(failedId)) {
655 throw new AssertionError("Configuration data model is corrupt. You must restart your server.");
656 }
657
658 skip.add(failedId);
659 }
660 }
661 }
662
663 monitor.finished();
664 if (!results.wasStarted(id)) {
665 throw new LifecycleException("restart", id, results);
666 }
667 return results;
668 }
669
670 public synchronized LifecycleResults unloadConfiguration(Artifact id) throws NoSuchConfigException {
671 return unloadConfiguration(id, NullLifecycleMonitor.INSTANCE);
672 }
673
674 public synchronized LifecycleResults unloadConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException {
675 if(!id.isResolved()) {
676 throw new IllegalArgumentException("Artifact "+id+" is not fully resolved");
677 }
678 Set started = configurationModel.getStarted();
679 LinkedHashSet unloadList = configurationModel.unload(id);
680
681 addConfigurationsToMonitor(monitor, unloadList);
682
683 LifecycleResults results = new LifecycleResults();
684 for (Iterator iterator = unloadList.iterator(); iterator.hasNext();) {
685 Artifact configurationId = (Artifact) iterator.next();
686 Configuration configuration = getConfiguration(configurationId);
687
688 // first make sure it is stopped
689 if (started.contains(configurationId)) {
690 monitor.stopping(configurationId);
691 stop(configuration);
692 monitor.succeeded(configurationId);
693 results.addStopped(configurationId);
694 } else {
695 // call stop just to be sure the beans aren't running
696 stop(configuration);
697 }
698
699 // now unload it
700 monitor.unloading(configurationId);
701 unload(configuration);
702 monitor.succeeded(configurationId);
703 results.addUnloaded(configurationId);
704
705 // clean up the model
706 removeConfigurationFromModel(configurationId);
707 }
708 monitor.finished();
709 return results;
710 }
711
712 protected void removeConfigurationFromModel(Artifact configurationId) throws NoSuchConfigException {
713 if(configurationModel.containsConfiguration(configurationId)) {
714 configurationModel.removeConfiguration(configurationId);
715 }
716 configurations.remove(configurationId);
717 }
718
719 protected void unload(Configuration configuration) {
720 try {
721 configuration.doStop();
722 } catch (Exception e) {
723 log.debug("Problem unloading config: " + configuration.getId(), e);
724 }
725 }
726
727 public synchronized LifecycleResults reloadConfiguration(Artifact id) throws NoSuchConfigException, LifecycleException {
728 return reloadConfiguration(id, NullLifecycleMonitor.INSTANCE);
729 }
730
731 public synchronized LifecycleResults reloadConfiguration(Artifact id, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
732 return reloadConfiguration(id, id.getVersion(), monitor);
733 }
734
735 public synchronized LifecycleResults reloadConfiguration(Artifact id, Version version) throws NoSuchConfigException, LifecycleException {
736 return reloadConfiguration(id, version, NullLifecycleMonitor.INSTANCE);
737 }
738
739 public synchronized LifecycleResults reloadConfiguration(Artifact id, Version version, LifecycleMonitor monitor) throws NoSuchConfigException, LifecycleException {
740 if(!id.isResolved()) {
741 throw new IllegalArgumentException("Artifact "+id+" is not fully resolved");
742 }
743 Configuration configuration = getConfiguration(id);
744 if (configuration == null) { // The configuration to reload is not currently loaded
745 ConfigurationData data = null;
746 List storeSnapshot = getStoreList();
747 for (int i = 0; i < storeSnapshot.size(); i++) {
748 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
749 if (store.containsConfiguration(id)) {
750 try {
751 data = store.loadConfiguration(id);
752 } catch (Exception e) {
753 log.warn("Unable to load existing configuration "+id+" from config store", e);
754 }
755 }
756 }
757 if(data == null) {
758 throw new NoSuchConfigException(id);
759 }
760 UnloadedConfiguration existingUnloadedConfiguration = new UnloadedConfiguration(data, new LinkedHashSet());
761 Artifact newId = new Artifact(id.getGroupId(), id.getArtifactId(), version, id.getType());
762 ConfigurationData newData = null;
763 try {
764 newData = loadConfigurationData(newId, monitor);
765 } catch (Exception e) {
766 monitor.finished();
767 throw new LifecycleException("reload", id, e);
768 }
769
770 return reloadConfiguration(existingUnloadedConfiguration, newData, monitor);
771 } else { // The configuration to reload is loaded
772 ConfigurationData existingConfigurationData = configuration.getConfigurationData();
773 UnloadedConfiguration existingUnloadedConfiguration = new UnloadedConfiguration(existingConfigurationData, getResolvedParentIds(configuration));
774
775 Artifact newId = new Artifact(id.getGroupId(), id.getArtifactId(), version, id.getType());
776
777 // reload the ConfigurationData from a store
778 ConfigurationData configurationData = null;
779 try {
780 configurationData = loadConfigurationData(newId, monitor);
781 } catch (Exception e) {
782 monitor.finished();
783 throw new LifecycleException("reload", id, e);
784 }
785
786 return reloadConfiguration(existingUnloadedConfiguration, configurationData, monitor);
787 }
788 }
789
790 public synchronized LifecycleResults reloadConfiguration(ConfigurationData configurationData) throws LifecycleException, NoSuchConfigException {
791 return reloadConfiguration(configurationData, NullLifecycleMonitor.INSTANCE);
792 }
793
794 public synchronized LifecycleResults reloadConfiguration(ConfigurationData configurationData, LifecycleMonitor monitor) throws LifecycleException, NoSuchConfigException {
795 Configuration configuration = getConfiguration(configurationData.getId());
796 if (configuration == null) {
797 throw new NoSuchConfigException(configurationData.getId());
798 }
799 ConfigurationData existingConfigurationData = configuration.getConfigurationData();
800 UnloadedConfiguration existingUnloadedConfiguration = new UnloadedConfiguration(existingConfigurationData, getResolvedParentIds(configuration));
801 return reloadConfiguration(existingUnloadedConfiguration, configurationData, monitor);
802 }
803
804 private boolean hasHardDependency(Artifact configurationId, ConfigurationData configurationData) {
805 for (Iterator iterator = configurationData.getEnvironment().getDependencies().iterator(); iterator.hasNext();) {
806 Dependency dependency = (Dependency) iterator.next();
807 Artifact artifact = dependency.getArtifact();
808 if (artifact.getVersion() != null && artifact.matches(configurationId)) {
809 return true;
810 }
811 }
812
813 for (Iterator iterator = configurationData.getChildConfigurations().values().iterator(); iterator.hasNext();) {
814 ConfigurationData childConfigurationData = (ConfigurationData) iterator.next();
815 if (hasHardDependency(configurationId, childConfigurationData)) {
816 return true;
817 }
818 }
819 return false;
820 }
821
822 // todo this method ignores garbage collection of configurations
823 private LifecycleResults reloadConfiguration(UnloadedConfiguration existingUnloadedConfiguration, ConfigurationData newConfigurationData, LifecycleMonitor monitor) throws LifecycleException, NoSuchConfigException {
824 boolean force = false;
825
826 Artifact existingConfigurationId = existingUnloadedConfiguration.getConfigurationData().getId();
827 Artifact newConfigurationId = newConfigurationData.getId();
828
829 //
830 // recursively load the new configuration; this will catch any new parents
831 //
832 LinkedHashMap newConfigurations = new LinkedHashMap();
833 try {
834 loadDepthFirst(newConfigurationData, newConfigurations, monitor);
835 } catch (Exception e) {
836 monitor.finished();
837 throw new LifecycleException("reload", newConfigurationId, e);
838 }
839
840 //
841 // get a list of the started configuration, so we can restart them later
842 //
843 Set started = configurationModel.getStarted();
844
845 //
846 // get a list of the child configurations that will need to reload
847 //
848 // note: we are iterating in reverse order
849 LinkedHashMap existingParents = new LinkedHashMap();
850 LinkedHashMap reloadChildren = new LinkedHashMap();
851 for (Iterator iterator = reverse(configurationModel.reload(existingConfigurationId)).iterator(); iterator.hasNext();) {
852 Artifact configurationId = (Artifact) iterator.next();
853
854 if (configurationId.equals(existingConfigurationId)) {
855 continue;
856 }
857
858 // if new configurations contains the child something we have a circular dependency
859 if (newConfigurations.containsKey(configurationId)) {
860 throw new LifecycleException("reload", newConfigurationId,
861 new IllegalStateException("Circular depenency between " + newConfigurationId + " and " + configurationId));
862 }
863
864 Configuration configuration = getConfiguration(configurationId);
865 ConfigurationData configurationData = configuration.getConfigurationData();
866
867 // save off the exising resolved parent ids in case we need to restore this configuration
868 LinkedHashSet existingParentIds = getResolvedParentIds(configuration);
869 existingParents.put(configurationId, existingParentIds);
870
871 // check that the child doen't have a hard dependency on the old configuration
872 LinkedHashSet resolvedParentIds = null;
873 if (hasHardDependency(existingConfigurationId, configurationData)) {
874 if (force) {
875 throw new LifecycleException("reload", newConfigurationId,
876 new IllegalStateException("Existing configuration " + configurationId + " has a hard dependency on the current version of this configuration " + existingConfigurationId));
877 }
878
879 // we leave the resolved parent ids null to signal that we should not reload the configuration
880 resolvedParentIds = null;
881 } else {
882 resolvedParentIds = new LinkedHashSet(existingParentIds);
883 resolvedParentIds.remove(existingConfigurationId);
884 resolvedParentIds.add(newConfigurationId);
885 }
886
887 reloadChildren.put(configurationId, new UnloadedConfiguration(configurationData, resolvedParentIds));
888 monitor.addConfiguration(configurationId);
889 }
890
891 //
892 // unload the children
893 //
894
895 // note: we are iterating in reverse order
896 LifecycleResults results = new LifecycleResults();
897 for (Iterator iterator = reverse(reloadChildren).keySet().iterator(); iterator.hasNext();) {
898 Artifact configurationId = (Artifact) iterator.next();
899 Configuration configuration = getConfiguration(configurationId);
900
901 // first make sure it is stopped
902 if (started.contains(configurationId)) {
903 monitor.stopping(configurationId);
904 stop(configuration);
905 monitor.succeeded(configurationId);
906 results.addStopped(configurationId);
907 } else {
908 // call stop just to be sure the beans aren't running
909 stop(configuration);
910 }
911
912 // now unload it
913 monitor.unloading(configurationId);
914 unload(configuration);
915 monitor.succeeded(configurationId);
916 results.addUnloaded(configurationId);
917 }
918
919 //
920 // unload the existing config
921 //
922 Configuration existingConfiguration = getConfiguration(existingConfigurationId);
923 if (started.contains(existingConfigurationId)) {
924 monitor.stopping(existingConfigurationId);
925 stop(existingConfiguration);
926 monitor.succeeded(existingConfigurationId);
927 results.addStopped(existingConfigurationId);
928 } else if(existingConfiguration != null) {
929 // call stop just to be sure the beans aren't running
930 stop(existingConfiguration);
931 }
932 if(existingConfiguration != null) {
933 monitor.unloading(existingConfigurationId);
934 unload(existingConfiguration);
935 monitor.succeeded(existingConfigurationId);
936 results.addUnloaded(existingConfigurationId);
937 }
938
939 //
940 // load the new configurations
941 //
942 boolean reinstatedExisting = false;
943 /* reduce variable scope */ {
944 Map loadedParents = new LinkedHashMap();
945 Map startedParents = new LinkedHashMap();
946 Configuration newConfiguration = null;
947 Artifact configurationId = null;
948 try {
949 //
950 // load all of the new configurations
951 //
952 for (Iterator iterator = newConfigurations.entrySet().iterator(); iterator.hasNext();) {
953 Map.Entry entry = (Map.Entry) iterator.next();
954 configurationId = (Artifact) entry.getKey();
955 UnloadedConfiguration unloadedConfiguration = (UnloadedConfiguration) entry.getValue();
956
957 monitor.loading(configurationId);
958 Configuration configuration = load(unloadedConfiguration.getConfigurationData(), unloadedConfiguration.getResolvedParentIds(), loadedParents);
959 monitor.succeeded(configurationId);
960
961 if (configurationId.equals(newConfigurationId)) {
962 newConfiguration = configuration;
963 reloadingConfiguration = configuration;
964 } else {
965 loadedParents.put(configurationId, configuration);
966 }
967 }
968
969 if (newConfiguration == null) {
970 AssertionError cause = new AssertionError("Internal error: configuration was not load");
971 results.addFailed(newConfigurationId, cause);
972 throw new LifecycleException("reload", newConfigurationId, results);
973 }
974
975 //
976 // start the new configurations if the old one was running
977 //
978 if (started.contains(existingConfigurationId)) {
979
980 // determine which of the parents we need to start
981 LinkedHashSet startList = new LinkedHashSet();
982 for (Iterator iterator = getStartParents(newConfiguration).iterator(); iterator.hasNext();) {
983 Configuration serviceParent = (Configuration) iterator.next();
984 if (loadedParents.containsKey(serviceParent.getId())) {
985 startList.add(serviceParent);
986 }
987 }
988
989 // start the new parents
990 for (Iterator iterator = startList.iterator(); iterator.hasNext();) {
991 Configuration startParent = (Configuration) iterator.next();
992 monitor.starting(configurationId);
993 start(startParent);
994 monitor.succeeded(configurationId);
995
996 startedParents.put(configurationId, startParent);
997 }
998
999 // start the new configuration
1000 monitor.starting(newConfigurationId);
1001 start(newConfiguration);
1002 monitor.succeeded(newConfigurationId);
1003 }
1004
1005 //
1006 // update the results
1007 //
1008 results.setLoaded(loadedParents.keySet());
1009 results.addLoaded(newConfigurationId);
1010 if (started.contains(existingConfigurationId)) {
1011 results.setStarted(startedParents.keySet());
1012 results.addStarted(newConfigurationId);
1013 }
1014
1015 //
1016 // update the model
1017 //
1018
1019 // add all of the new configurations the model
1020 addNewConfigurationsToModel(loadedParents);
1021
1022 // now ugrade the existing node in the model
1023 if(configurationModel.containsConfiguration(existingConfigurationId)) {
1024 configurationModel.upgradeConfiguration(existingConfigurationId,
1025 newConfigurationId,
1026 getConfigurationIds(getLoadParents(newConfiguration)),
1027 getConfigurationIds(getStartParents(newConfiguration)));
1028 } else {
1029 configurationModel.addConfiguation(newConfigurationId,
1030 getConfigurationIds(getLoadParents(newConfiguration)),
1031 getConfigurationIds(getStartParents(newConfiguration)));
1032 load(newConfigurationId);
1033 }
1034
1035 // replace the configuraiton in he configurations map
1036 configurations.remove(existingConfiguration);
1037 configurations.put(newConfigurationId, newConfiguration);
1038
1039 // migrate the configuration settings
1040 migrateConfiguration(existingConfigurationId, newConfigurationId, newConfiguration, started.contains(existingConfigurationId));
1041 } catch (Exception e) {
1042 monitor.failed(configurationId, e);
1043 results.addFailed(configurationId, e);
1044
1045 //
1046 // stop and unload all configurations that were actually loaded
1047 //
1048 for (Iterator iterator = startedParents.values().iterator(); iterator.hasNext();) {
1049 Configuration configuration = (Configuration) iterator.next();
1050 stop(configuration);
1051 }
1052 for (Iterator iterator = loadedParents.values().iterator(); iterator.hasNext();) {
1053 Configuration configuration = (Configuration) iterator.next();
1054 unload(configuration);
1055 }
1056
1057 // stop and unload the newConfiguration
1058 if (newConfiguration != null) {
1059 stop(newConfiguration);
1060 unload(newConfiguration);
1061 }
1062
1063 //
1064 // atempt to reinstate the old configuation
1065 //
1066 Configuration configuration = null;
1067 try {
1068 configuration = load(existingUnloadedConfiguration.getConfigurationData(),
1069 existingUnloadedConfiguration.getResolvedParentIds(),
1070 Collections.EMPTY_MAP);
1071 reloadingConfiguration = configuration;
1072 // if the configuration was started before restart it
1073 if (started.contains(existingConfigurationId)) {
1074 start(configuration);
1075 results.addStarted(existingConfigurationId);
1076 }
1077
1078 // don't mark as loded until start completes as it may thorw an exception
1079 results.addLoaded(existingConfigurationId);
1080
1081 configurations.put(existingConfigurationId, configuration);
1082
1083 reinstatedExisting = true;
1084 } catch (Exception ignored) {
1085 monitor.failed(existingConfigurationId, e);
1086
1087 // we tried our best
1088 if (configuration != null) {
1089 unload(configuration);
1090 }
1091
1092 //
1093 // cleanup the model
1094 //
1095 for (Iterator iterator = results.getUnloaded().iterator(); iterator.hasNext();) {
1096 Artifact childId = (Artifact) iterator.next();
1097 configurationModel.unload(childId);
1098 removeConfigurationFromModel(childId);
1099 }
1100
1101 throw new LifecycleException("reload", newConfigurationId, results);
1102 }
1103 } finally {
1104 reloadingConfiguration = null;
1105 }
1106 }
1107
1108 //
1109 // reload as many child configurations as possible
1110 //
1111 Set skip = new HashSet();
1112 for (Iterator iterator = reloadChildren.entrySet().iterator(); iterator.hasNext();) {
1113 Map.Entry entry = (Map.Entry) iterator.next();
1114 Artifact configurationId = (Artifact) entry.getKey();
1115 UnloadedConfiguration unloadedConfiguration = (UnloadedConfiguration) entry.getValue();
1116
1117 // skip the configurations that have alredy failed or are children of failed configurations
1118 if (skip.contains(configurationId)) {
1119 continue;
1120 }
1121
1122 // try to load the configuation
1123 Configuration configuration = null;
1124 try {
1125 // get the correct resolved parent ids based on if we are loading with the new config id or the existing one
1126 LinkedHashSet resolvedParentIds;
1127 if (!reinstatedExisting) {
1128 resolvedParentIds = unloadedConfiguration.getResolvedParentIds();
1129 } else {
1130 resolvedParentIds = (LinkedHashSet) existingParents.get(configurationId);
1131 }
1132
1133 // if the resolved parent ids is null, then we are not supposed to reload this configuration
1134 if (resolvedParentIds != null) {
1135 monitor.loading(configurationId);
1136 configuration = load(unloadedConfiguration.getConfigurationData(), resolvedParentIds, Collections.EMPTY_MAP);
1137 reloadingConfiguration = configuration;
1138 monitor.succeeded(configurationId);
1139
1140
1141 // if the configuration was started before restart it
1142 if (started.contains(configurationId)) {
1143 monitor.starting(configurationId);
1144 start(configuration);
1145 monitor.succeeded(configurationId);
1146 results.addStarted(configurationId);
1147 }
1148
1149 // don't mark as loded until start completes as it may thow an exception
1150 results.addLoaded(configurationId);
1151
1152 configurations.put(configurationId, configuration);
1153 } else {
1154 removeConfigurationFromModel(configurationId);
1155 }
1156 } catch (Exception e) {
1157 // the configuraiton failed to restart
1158 results.addFailed(configurationId, e);
1159 monitor.failed(configurationId, e);
1160 skip.add(configurationId);
1161
1162 // unload the configuration if it was loaded and failed in start
1163 if (configuration != null) {
1164 unload(configuration);
1165 }
1166
1167 // officially unload the configuration in the model (without gc)
1168 LinkedHashSet unloadList = configurationModel.unload(configurationId, false);
1169 configurationModel.removeConfiguration(configurationId);
1170
1171 // all of the configurations to be unloaded must be in our unloaded list, or the model is corrupt
1172 if (!reloadChildren.keySet().containsAll(unloadList)) {
1173 throw new AssertionError("Configuration data model is corrupt. You must restart your server.");
1174 }
1175
1176 // add the children of the failed configuration to the results as unloaded
1177 for (Iterator iterator1 = unloadList.iterator(); iterator1.hasNext();) {
1178 Artifact failedId = (Artifact) iterator1.next();
1179
1180 // if any of the failed configuration are in the reloaded set, the model is
1181 // corrupt because we loaded a child before a parent
1182 if (results.wasLoaded(failedId)) {
1183 throw new AssertionError("Configuration data model is corrupt. You must restart your server.");
1184 }
1185
1186 skip.add(failedId);
1187 }
1188 } finally {
1189 reloadingConfiguration = null;
1190 }
1191 }
1192
1193 //
1194 // If nothing failed, delete all the unloaded modules that weren't reloaded
1195 //
1196 if(!results.wasLoaded(existingConfigurationId) && !results.wasFailed(existingConfigurationId)) {
1197 try {
1198 uninstallConfiguration(existingConfigurationId);
1199 } catch (IOException e) {
1200 log.error("Unable to uninstall configuration "+existingConfigurationId, e);
1201 }
1202 }
1203
1204 monitor.finished();
1205 if (results.wasFailed(newConfigurationId) || !results.wasLoaded(newConfigurationId)) {
1206 throw new LifecycleException("restart", newConfigurationId, results);
1207 }
1208 return results;
1209 }
1210
1211 protected void migrateConfiguration(Artifact oldName, Artifact newName, Configuration configuration, boolean running) throws NoSuchConfigException {
1212 }
1213
1214 private static LinkedHashSet getResolvedParentIds(Configuration configuration) {
1215 LinkedHashSet resolvedParentIds = new LinkedHashSet();
1216 for (Iterator iterator = configuration.getClassParents().iterator(); iterator.hasNext();) {
1217 Configuration classParent = (Configuration) iterator.next();
1218 resolvedParentIds.add(classParent.getId());
1219 }
1220 for (Iterator iterator = configuration.getServiceParents().iterator(); iterator.hasNext();) {
1221 Configuration serviceParent = (Configuration) iterator.next();
1222 resolvedParentIds.add(serviceParent.getId());
1223 }
1224 for (Iterator iterator = configuration.getChildren().iterator(); iterator.hasNext();) {
1225 Configuration child = (Configuration) iterator.next();
1226 resolvedParentIds.addAll(getResolvedParentIds(child));
1227 }
1228
1229 return resolvedParentIds;
1230 }
1231
1232 public synchronized void uninstallConfiguration(Artifact configurationId) throws IOException, NoSuchConfigException {
1233 if(!configurationId.isResolved()) {
1234 throw new IllegalArgumentException("Artifact "+configurationId+" is not fully resolved");
1235 }
1236 if (configurations.containsKey(configurationId)) {
1237 if(isRunning(configurationId)) {
1238 stopConfiguration(configurationId);
1239 }
1240 if(isLoaded((configurationId))) {
1241 unloadConfiguration(configurationId);
1242 }
1243 }
1244
1245 uninstall(configurationId);
1246 List storeSnapshot = getStoreList();
1247 for (int i = 0; i < storeSnapshot.size(); i++) {
1248 ConfigurationStore store = (ConfigurationStore) storeSnapshot.get(i);
1249 if(store.containsConfiguration(configurationId)) {
1250 store.uninstall(configurationId);
1251 }
1252 }
1253
1254 removeConfigurationFromModel(configurationId);
1255 notifyWatchers(configurationId);
1256 }
1257
1258 protected void uninstall(Artifact configurationId) {
1259 //child class can override this method
1260 }
1261
1262 private void notifyWatchers(Artifact id) {
1263 for (Iterator it = watchers.iterator(); it.hasNext();) {
1264 DeploymentWatcher watcher = (DeploymentWatcher) it.next();
1265 watcher.undeployed(id);
1266 }
1267 }
1268
1269 public ArtifactResolver getArtifactResolver() {
1270 return artifactResolver;
1271 }
1272
1273 /**
1274 * this configuration manager never starts configurations.
1275 * @return false
1276 */
1277 public boolean isOnline() {
1278 return false;
1279 }
1280
1281 public void setOnline(boolean online) {
1282 }
1283
1284 private List getStoreList() {
1285 return new ArrayList(stores);
1286 }
1287
1288 private static void addConfigurationsToMonitor(LifecycleMonitor monitor, LinkedHashSet configurations) {
1289 for (Iterator iterator = configurations.iterator(); iterator.hasNext();) {
1290 Artifact configurationId = (Artifact) iterator.next();
1291 monitor.addConfiguration(configurationId);
1292 }
1293 }
1294
1295 private static LinkedHashSet reverse(LinkedHashSet set) {
1296 ArrayList reverseList = new ArrayList(set);
1297 Collections.reverse(reverseList);
1298 set = new LinkedHashSet(reverseList);
1299 return set;
1300 }
1301
1302 private static LinkedHashMap reverse(LinkedHashMap map) {
1303 ArrayList reverseEntrySet = new ArrayList(map.entrySet());
1304 Collections.reverse(reverseEntrySet);
1305
1306 map = new LinkedHashMap(reverseEntrySet.size());
1307 for (Iterator iterator = reverseEntrySet.iterator(); iterator.hasNext();) {
1308 Map.Entry entry = (Map.Entry) iterator.next();
1309 Object key = entry.getKey();
1310 Object value = entry.getValue();
1311 map.put(key, value);
1312 }
1313 return map;
1314 }
1315
1316 public static final GBeanInfo GBEAN_INFO;
1317
1318 static {
1319 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(SimpleConfigurationManager.class, "ConfigurationManager");
1320 infoFactory.addReference("Stores", ConfigurationStore.class, "ConfigurationStore");
1321 infoFactory.addReference("ArtifactResolver", ArtifactResolver.class, "ArtifactResolver");
1322 infoFactory.addReference("Repositories", Repository.class, "Repository");
1323 infoFactory.addReference("Watchers", DeploymentWatcher.class);
1324 infoFactory.addInterface(ConfigurationManager.class);
1325 infoFactory.setConstructor(new String[]{"Stores", "ArtifactResolver", "Repositories", "Watchers"});
1326 GBEAN_INFO = infoFactory.getBeanInfo();
1327 }
1328
1329 public static GBeanInfo getGBeanInfo() {
1330 return GBEAN_INFO;
1331 }
1332
1333 }