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