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 }