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 }