1 /**
2 *
3 * Copyright 2003-2004 The Apache Software Foundation
4 *
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
8 *
9 * http://www.apache.org/licenses/LICENSE-2.0
10 *
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
16 */
17
18 package org.apache.geronimo.kernel.config;
19
20 import java.io.File;
21 import java.io.IOException;
22 import java.net.MalformedURLException;
23 import java.net.URL;
24 import java.util.ArrayList;
25 import java.util.Collection;
26 import java.util.Collections;
27 import java.util.HashMap;
28 import java.util.Iterator;
29 import java.util.LinkedHashSet;
30 import java.util.List;
31 import java.util.ListIterator;
32 import java.util.Map;
33 import java.util.Set;
34
35 import javax.management.MalformedObjectNameException;
36 import javax.management.ObjectName;
37
38 import org.apache.commons.logging.Log;
39 import org.apache.commons.logging.LogFactory;
40 import org.apache.geronimo.gbean.AbstractName;
41 import org.apache.geronimo.gbean.AbstractNameQuery;
42 import org.apache.geronimo.gbean.GBeanData;
43 import org.apache.geronimo.gbean.GBeanInfo;
44 import org.apache.geronimo.gbean.GBeanInfoBuilder;
45 import org.apache.geronimo.gbean.GBeanLifecycle;
46 import org.apache.geronimo.gbean.ReferencePatterns;
47 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
48 import org.apache.geronimo.kernel.GBeanNotFoundException;
49 import org.apache.geronimo.kernel.Naming;
50 import org.apache.geronimo.kernel.classloader.JarFileClassLoader;
51 import org.apache.geronimo.kernel.repository.Artifact;
52 import org.apache.geronimo.kernel.repository.Dependency;
53 import org.apache.geronimo.kernel.repository.Environment;
54 import org.apache.geronimo.kernel.repository.ImportType;
55 import org.apache.geronimo.kernel.repository.MissingDependencyException;
56
57 /**
58 * A Configuration represents a collection of runnable services that can be
59 * loaded into a Geronimo Kernel and brought online. The primary components in
60 * a Configuration are a codebase, represented by a collection of URLs that
61 * is used to locate classes, and a collection of GBean instances that define
62 * its state.
63 * <p/>
64 * The persistent attributes of the Configuration are:
65 * <ul>
66 * <li>its unique configId used to identify this specific config</li>
67 * <li>the configId of a parent Configuration on which this one is dependent</li>
68 * <li>a List<URI> of code locations (which may be absolute or relative to a baseURL)</li>
69 * <li>a byte[] holding the state of the GBeans instances in Serialized form</li>
70 * </ul>
71 * When a configuration is started, it converts the URIs into a set of absolute
72 * URLs by resolving them against the specified baseURL (this would typically
73 * be the root of the CAR file which contains the configuration) and then
74 * constructs a ClassLoader for that codebase. That ClassLoader is then used
75 * to de-serialize the persisted GBeans, ensuring the GBeans can be recycled
76 * as necessary. Once the GBeans have been restored, they are brought online
77 * by registering them with the MBeanServer.
78 * <p/>
79 * A dependency on the Configuration is created for every GBean it loads. As a
80 * result, a startRecursive() operation on the configuration will result in
81 * a startRecursive() for all the GBeans it contains. Similarly, if the
82 * Configuration is stopped then all of its GBeans will be stopped as well.
83 *
84 * @version $Rev:385718 $ $Date: 2006-11-06 02:28:54 -0800 (Mon, 06 Nov 2006) $
85 */
86 public class Configuration implements GBeanLifecycle, ConfigurationParent {
87 private static final Log log = LogFactory.getLog(Configuration.class);
88
89 /**
90 * Converts an Artifact to an AbstractName for a configuration. Does not
91 * validate that this is a reasonable or resolved Artifact, or that it
92 * corresponds to an actual Configuration.
93 */
94 public static AbstractName getConfigurationAbstractName(Artifact configId) throws InvalidConfigException {
95 return new AbstractName(configId, Collections.singletonMap("configurationName", configId.toString()), getConfigurationObjectName(configId));
96 }
97
98 public static boolean isConfigurationObjectName(ObjectName name) {
99 return name.getDomain().equals("geronimo.config") && name.getKeyPropertyList().size() == 1 && name.getKeyProperty("name") != null;
100 }
101
102 public static Artifact getConfigurationID(ObjectName objectName) {
103 if (isConfigurationObjectName(objectName)) {
104 String name = ObjectName.unquote(objectName.getKeyProperty("name"));
105 return Artifact.create(name);
106 } else {
107 throw new IllegalArgumentException("ObjectName " + objectName + " is not a Configuration name");
108 }
109 }
110
111 private static ObjectName getConfigurationObjectName(Artifact configId) throws InvalidConfigException {
112 try {
113 return new ObjectName("geronimo.config:name=" + ObjectName.quote(configId.toString()));
114 } catch (MalformedObjectNameException e) {
115 throw new InvalidConfigException("Could not construct object name for configuration", e);
116 }
117 }
118
119 /**
120 * The artifact id for this configuration.
121 */
122 private final Artifact id;
123
124 /**
125 * The registered abstractName for this configuraion.
126 */
127 private final AbstractName abstractName;
128
129 /**
130 * Defines the environment requred for this configuration.
131 */
132 private final Environment environment;
133
134 /**
135 * Used to resolve dependecies and paths
136 */
137 private final ConfigurationResolver configurationResolver;
138
139 /**
140 * Parent configurations used for class loader.
141 */
142 private final List classParents = new ArrayList();
143
144 /**
145 * Parent configuations used for service resolution.
146 */
147 private final List serviceParents = new ArrayList();
148
149 /**
150 * All service parents depth first
151 */
152 private final List allServiceParents = new ArrayList();
153
154 /**
155 * Artifacts added to the class loader (non-configuation artifacts).
156 */
157 private final LinkedHashSet dependencies = new LinkedHashSet();
158
159 /**
160 * The GBeanData objects by ObjectName
161 */
162 private final Map gbeans = new HashMap();
163
164 /**
165 * The classloader used to load the child GBeans contained in this configuration.
166 */
167 private final MultiParentClassLoader configurationClassLoader;
168
169 /**
170 * The relative class path (URI) of this configuation.
171 */
172 private final LinkedHashSet classPath;
173
174 /**
175 * Naming system used when generating a name for a new gbean
176 */
177 private final Naming naming;
178
179 /**
180 * Environment, classpath, gbeans and other data for this configuration.
181 */
182 private ConfigurationData configurationData;
183
184 /**
185 * The nested configurations of this configuration.
186 */
187 List children = new ArrayList();
188
189 /**
190 * The parent of this configuration;
191 */
192 private Configuration parent = null;
193
194 /**
195 * Only used to allow declaration as a reference.
196 */
197 public Configuration() {
198 id = null;
199 abstractName = null;
200 environment = null;
201 classPath = null;
202 configurationResolver = null;
203 configurationClassLoader = null;
204 naming = null;
205 }
206
207 /**
208 * Creates a configuration.
209 * @param parents parents of this configuation (not ordered)
210 * @param configurationData the module type, environment and classpath of the configuration
211 * @param configurationResolver used to resolve dependecies and paths
212 */
213 public Configuration(Collection parents,
214 ConfigurationData configurationData,
215 ConfigurationResolver configurationResolver,
216 ManageableAttributeStore attributeStore) throws MissingDependencyException, MalformedURLException, NoSuchConfigException, InvalidConfigException {
217 if (parents == null) parents = Collections.EMPTY_SET;
218 if (configurationData == null) throw new NullPointerException("configurationData is null");
219 if (configurationResolver == null) throw new NullPointerException("configurationResolver is null");
220
221 this.configurationData = configurationData;
222 this.environment = configurationData.getEnvironment();
223 this.configurationResolver = configurationResolver;
224 this.classPath = new LinkedHashSet(configurationData.getClassPath());
225 this.naming = configurationData.getNaming();
226
227 this.id = environment.getConfigId();
228 abstractName = getConfigurationAbstractName(id);
229
230
231
232
233 List transtiveDependencies = configurationResolver.resolveTransitiveDependencies(parents, environment.getDependencies());
234
235
236
237
238 Map parentsById = new HashMap();
239 for (Iterator iterator = parents.iterator(); iterator.hasNext();) {
240 Configuration configuration = (Configuration) iterator.next();
241 Artifact id = configuration.getId();
242 parentsById.put(id, configuration);
243 }
244
245 for (Iterator iterator = transtiveDependencies.iterator(); iterator.hasNext();) {
246 Dependency dependency = (Dependency) iterator.next();
247 Artifact artifact = dependency.getArtifact();
248 if (parentsById.containsKey(artifact)) {
249 Configuration parent = (Configuration) parentsById.get(artifact);
250 if (dependency.getImportType() == ImportType.CLASSES || dependency.getImportType() == ImportType.ALL) {
251 classParents.add(parent);
252 }
253 if (dependency.getImportType() == ImportType.SERVICES || dependency.getImportType() == ImportType.ALL) {
254 serviceParents.add(parent);
255 }
256 } else if (dependency.getImportType() == ImportType.SERVICES) {
257 throw new IllegalStateException("Could not find parent " + artifact + " in the parents collection");
258 } else {
259 dependencies.add(artifact);
260 }
261 }
262
263 try {
264
265
266
267 configurationClassLoader = createConfigurationClasssLoader(parents, environment, classPath);
268
269
270
271
272 addDepthFirstServiceParents(this, allServiceParents);
273
274
275
276
277 Collection gbeans = configurationData.getGBeans(configurationClassLoader);
278 if (attributeStore != null) {
279 gbeans = attributeStore.applyOverrides(id, gbeans, configurationClassLoader);
280 }
281 for (Iterator iterator = gbeans.iterator(); iterator.hasNext();) {
282 GBeanData gbeanData = (GBeanData) iterator.next();
283 this.gbeans.put(gbeanData.getAbstractName(), gbeanData);
284 }
285
286
287
288
289 LinkedHashSet childParents = new LinkedHashSet(parents);
290 childParents.add(this);
291 for (Iterator iterator = configurationData.getChildConfigurations().entrySet().iterator(); iterator.hasNext();) {
292 Map.Entry entry = (Map.Entry) iterator.next();
293 String moduleName = (String) entry.getKey();
294 ConfigurationData childConfigurationData = (ConfigurationData) entry.getValue();
295 Configuration childConfiguration = new Configuration(childParents, childConfigurationData, configurationResolver.createChildResolver(moduleName), attributeStore);
296 childConfiguration.parent = this;
297 children.add(childConfiguration);
298 }
299 } catch (RuntimeException e) {
300 shutdown();
301 throw e;
302 } catch (Error e) {
303 shutdown();
304 throw e;
305 } catch (MissingDependencyException e) {
306 shutdown();
307 throw e;
308 } catch (MalformedURLException e) {
309 shutdown();
310 throw e;
311 } catch (NoSuchConfigException e) {
312 shutdown();
313 throw e;
314 } catch (InvalidConfigException e) {
315 shutdown();
316 throw e;
317 }
318 }
319
320 private MultiParentClassLoader createConfigurationClasssLoader(Collection parents, Environment environment, LinkedHashSet classPath) throws MalformedURLException, MissingDependencyException, NoSuchConfigException {
321
322 URL[] urls = buildClassPath(classPath);
323
324
325 ClassLoader[] parentClassLoaders;
326 if (parents.size() == 0 && classParents.size() == 0) {
327
328
329
330 parentClassLoaders = new ClassLoader[] {getClass().getClassLoader()};
331 } else {
332 parentClassLoaders = new ClassLoader[classParents.size()];
333 for (ListIterator iterator = classParents.listIterator(); iterator.hasNext();) {
334 Configuration configuration = (Configuration) iterator.next();
335 parentClassLoaders[iterator.previousIndex()] = configuration.getConfigurationClassLoader();
336 }
337 }
338
339
340 Set hiddenClassesSet = environment.getHiddenClasses();
341 String[] hiddenClasses = (String[]) hiddenClassesSet.toArray(new String[hiddenClassesSet.size()]);
342
343
344 LinkedHashSet nonOverridableSet = new LinkedHashSet();
345 for (Iterator iterator = classParents.iterator(); iterator.hasNext();) {
346 Configuration parent = (Configuration) iterator.next();
347
348 Environment parentEnvironment = parent.getEnvironment();
349 nonOverridableSet.addAll(parentEnvironment.getNonOverrideableClasses());
350 }
351 String[] nonOverridableClasses = (String[]) nonOverridableSet.toArray(new String[nonOverridableSet.size()]);
352
353 if (log.isDebugEnabled()) {
354 StringBuffer buf = new StringBuffer("ClassLoader structure for configuration ").append(id).append("\n");
355 buf.append("Parent configurations:\n");
356 for (Iterator iterator = classParents.iterator(); iterator.hasNext();) {
357 Configuration configuration = (Configuration) iterator.next();
358 buf.append(" ").append(configuration.getId()).append("\n");
359 }
360 buf.append("ClassPath:\n");
361 for (int i = 0; i < urls.length; i++) {
362 URL url = urls[i];
363 buf.append(" ").append(url).append("\n");
364 }
365 log.debug(buf.toString());
366 }
367
368 if (Boolean.getBoolean("Xorg.apache.geronimo.OldClassLoader")) {
369 return new MultiParentClassLoader(environment.getConfigId(),
370 urls,
371 parentClassLoaders,
372 environment.isInverseClassLoading(),
373 hiddenClasses,
374 nonOverridableClasses);
375 } else {
376 return new JarFileClassLoader(environment.getConfigId(),
377 urls,
378 parentClassLoaders,
379 environment.isInverseClassLoading(),
380 hiddenClasses,
381 nonOverridableClasses);
382 }
383 }
384
385 private void addDepthFirstServiceParents(Configuration configuration, List ancestors) {
386 ancestors.add(configuration);
387 for (Iterator parents = configuration.getServiceParents().iterator(); parents.hasNext();) {
388 Configuration parent = (Configuration) parents.next();
389 addDepthFirstServiceParents(parent, ancestors);
390 }
391 }
392
393 private URL[] buildClassPath(LinkedHashSet classPath) throws MalformedURLException, MissingDependencyException, NoSuchConfigException {
394 List urls = new ArrayList();
395 for (Iterator i = dependencies.iterator(); i.hasNext();) {
396 Artifact artifact = (Artifact) i.next();
397 File file = configurationResolver.resolve(artifact);
398 urls.add(file.toURL());
399 }
400 if (classPath != null) {
401 for (Iterator i = classPath.iterator(); i.hasNext();) {
402 String pattern = (String) i.next();
403 Set matches = configurationResolver.resolve(pattern);
404 for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
405 URL url = (URL) iterator.next();
406 urls.add(url);
407 }
408 }
409 }
410 return (URL[]) urls.toArray(new URL[urls.size()]);
411 }
412
413 /**
414 * Return the unique Id
415 * @return the unique Id
416 */
417 public Artifact getId() {
418 return id;
419 }
420
421 /**
422 * Gets the unique name of this configuration within the kernel.
423 * @return the unique name of this configuration
424 */
425 public String getObjectName() {
426 try {
427 return getConfigurationObjectName(id).getCanonicalName();
428 } catch (InvalidConfigException e) {
429 throw new AssertionError(e);
430 }
431 }
432
433 public AbstractName getAbstractName() {
434 return abstractName;
435 }
436
437 /**
438 * Gets the parent configurations used for class loading.
439 * @return the parents of this configuration used for class loading
440 */
441 public List getClassParents() {
442 return classParents;
443 }
444
445 /**
446 * Gets the parent configurations used for service resolution.
447 * @return the parents of this configuration used for service resolution
448 */
449 public List getServiceParents() {
450 return serviceParents;
451 }
452
453 /**
454 * Gets the artifact dependencies of this configuration.
455 * @return the artifact dependencies of this configuration
456 */
457 public LinkedHashSet getDependencies() {
458 return dependencies;
459 }
460
461 /**
462 * Gets the declaration of the environment in which this configuration runs.
463 * @return the environment of this configuration
464 */
465 public Environment getEnvironment() {
466 return environment;
467 }
468
469 /**
470 * This is used by the configuration manager to restart an existing configuation.
471 * Do not modify the configuation data.
472 * @return the configuation data for this configuration; do not modify
473 */
474 ConfigurationData getConfigurationData() {
475 return configurationData;
476 }
477
478 /**
479 * @deprecated this is only exposed temporarily for configuration manager
480 */
481 public ConfigurationResolver getConfigurationResolver() {
482 return configurationResolver;
483 }
484
485 /**
486 * Gets the relative class path (URIs) of this configuration.
487 * @return the relative class path of this configuation
488 */
489 public List getClassPath() {
490 return new ArrayList(classPath);
491 }
492
493 public void addToClassPath(String pattern) throws IOException {
494 if (!classPath.contains(pattern)) {
495 try {
496 Set matches = configurationResolver.resolve(pattern);
497 for (Iterator iterator = matches.iterator(); iterator.hasNext();) {
498 URL url = (URL) iterator.next();
499 configurationClassLoader.addURL(url);
500 }
501 classPath.add(pattern);
502 } catch (Exception e) {
503 throw new IOException("Unable to extend classpath with " + pattern);
504 }
505 }
506 }
507
508 /**
509 * Gets the type of the configuration (WAR, RAR et cetera)
510 * @return Type of the configuration.
511 */
512 public ConfigurationModuleType getModuleType() {
513 return configurationData.getModuleType();
514 }
515
516 /**
517 * Gets the time at which this configuration was created (or deployed).
518 * @return the time at which this configuration was created (or deployed)
519 */
520 public long getCreated() {
521 return configurationData.getCreated();
522 }
523
524 /**
525 * Gets the class loader for this configuration.
526 * @return the class loader for this configuration
527 */
528 public ClassLoader getConfigurationClassLoader() {
529 return configurationClassLoader;
530 }
531
532 /**
533 * Gets the nested configurations of this configuration. That is, the
534 * configurations within this one as a WAR can be within an EAR; not
535 * including wholly separate configurations that just depend on this
536 * one as a parent.
537 *
538 * @return the nested configuration of this configuration
539 */
540 public List getChildren() {
541 return Collections.unmodifiableList(children);
542 }
543
544 /**
545 * Gets the configurations owned by this configuration. This is only used for cascade-uninstall.
546 * @return the configurations owned by this configuration
547 */
548 public Set getOwnedConfigurations() {
549 return configurationData.getOwnedConfigurations();
550 }
551
552 /**
553 * Gets an unmodifiable collection of the GBeanDatas for the GBeans in this configuration.
554 * @return the GBeans in this configuration
555 */
556 public Map getGBeans() {
557 return Collections.unmodifiableMap(gbeans);
558 }
559
560 /**
561 * Determines of this configuration constains the specified GBean.
562 * @param gbean the name of the GBean
563 * @return true if this configuration contains the specified GBean; false otherwise
564 */
565 public synchronized boolean containsGBean(AbstractName gbean) {
566 return gbeans.containsKey(gbean);
567 }
568
569 /**
570 * Gets the enclosing configuration of this one (e.g. the EAR for a WAR),
571 * or null if it has none.
572 */
573 public Configuration getEnclosingConfiguration() {
574 return parent;
575 }
576
577 public synchronized AbstractName addGBean(String name, GBeanData gbean) throws GBeanAlreadyExistsException {
578 AbstractName abstractName = gbean.getAbstractName();
579 if (abstractName != null) {
580 throw new IllegalArgumentException("gbean already has an abstract name: " + abstractName);
581 }
582
583 String j2eeType = gbean.getGBeanInfo().getJ2eeType();
584 if (j2eeType == null) j2eeType = "GBean";
585 abstractName = naming.createRootName(id, name, j2eeType);
586 gbean.setAbstractName(abstractName);
587
588 if (gbeans.containsKey(abstractName)) {
589 throw new GBeanAlreadyExistsException(gbean.getAbstractName().toString());
590 }
591 gbeans.put(abstractName, gbean);
592 return abstractName;
593 }
594
595 public synchronized void addGBean(GBeanData gbean) throws GBeanAlreadyExistsException {
596 if (gbeans.containsKey(gbean.getAbstractName())) {
597 throw new GBeanAlreadyExistsException(gbean.getAbstractName().toString());
598 }
599 gbeans.put(gbean.getAbstractName(), gbean);
600 }
601
602 public synchronized void removeGBean(AbstractName name) throws GBeanNotFoundException {
603 if (!gbeans.containsKey(name)) {
604 throw new GBeanNotFoundException(name);
605 }
606 gbeans.remove(name);
607 }
608
609 public AbstractName findGBean(AbstractNameQuery pattern) throws GBeanNotFoundException {
610 if (pattern == null) throw new NullPointerException("pattern is null");
611 return findGBean(Collections.singleton(pattern));
612 }
613
614 public GBeanData findGBeanData(AbstractNameQuery pattern) throws GBeanNotFoundException {
615 if (pattern == null) throw new NullPointerException("pattern is null");
616 return findGBeanData(Collections.singleton(pattern));
617 }
618
619 public AbstractName findGBean(ReferencePatterns referencePatterns) throws GBeanNotFoundException {
620 if (referencePatterns == null) throw new NullPointerException("referencePatterns is null");
621 if (referencePatterns.isResolved()) {
622 return referencePatterns.getAbstractName();
623 }
624
625
626 Set patterns = referencePatterns.getPatterns();
627 return findGBean(patterns);
628 }
629
630 public AbstractName findGBean(Set patterns) throws GBeanNotFoundException {
631 if (patterns == null) throw new NullPointerException("patterns is null");
632 return findGBeanData(patterns).getAbstractName();
633 }
634
635 public GBeanData findGBeanData(Set patterns) throws GBeanNotFoundException {
636 if (patterns == null) throw new NullPointerException("patterns is null");
637 Set result = findGBeanDatas(this, patterns);
638 if (result.size() > 1) {
639 throw new GBeanNotFoundException("More than one match to referencePatterns", patterns);
640 } else if (result.size() == 1) {
641 return (GBeanData) result.iterator().next();
642 }
643
644
645 for (Iterator iterator = allServiceParents.iterator(); iterator.hasNext();) {
646 Configuration configuration = (Configuration) iterator.next();
647 result.addAll(findGBeanDatas(configuration, patterns));
648
649
650 if (result.size() > 1) {
651 List names = new ArrayList(result.size());
652 for (Iterator iterator1 = result.iterator(); iterator1.hasNext();) {
653 GBeanData gBeanData = (GBeanData) iterator1.next();
654 names.add(gBeanData.getAbstractName());
655 }
656 throw new GBeanNotFoundException("More than one match to referencePatterns: " + names.toString(), patterns);
657 }
658 }
659
660 if (result.isEmpty()) {
661 throw new GBeanNotFoundException("No matches for referencePatterns", patterns);
662 }
663
664 return (GBeanData) result.iterator().next();
665 }
666
667 public LinkedHashSet findGBeans(AbstractNameQuery pattern) {
668 if (pattern == null) throw new NullPointerException("pattern is null");
669 return findGBeans(Collections.singleton(pattern));
670 }
671
672 public LinkedHashSet findGBeans(ReferencePatterns referencePatterns) {
673 if (referencePatterns == null) throw new NullPointerException("referencePatterns is null");
674 if (referencePatterns.getAbstractName() != null) {
675
676 LinkedHashSet result = new LinkedHashSet();
677 result.add(referencePatterns.getAbstractName());
678 return result;
679 }
680
681
682 Set patterns = referencePatterns.getPatterns();
683 return findGBeans(patterns);
684 }
685
686 public LinkedHashSet findGBeans(Set patterns) {
687 if (patterns == null) throw new NullPointerException("patterns is null");
688 LinkedHashSet datas = findGBeanDatas(patterns);
689 LinkedHashSet result = new LinkedHashSet(datas.size());
690 for (Iterator iterator = datas.iterator(); iterator.hasNext();) {
691 GBeanData gBeanData = (GBeanData) iterator.next();
692 result.add(gBeanData.getAbstractName());
693 }
694
695 return result;
696 }
697
698 public LinkedHashSet findGBeanDatas(Set patterns) {
699 if (patterns == null) throw new NullPointerException("patterns is null");
700 LinkedHashSet datas = findGBeanDatas(this, patterns);
701
702
703 for (Iterator iterator = allServiceParents.iterator(); iterator.hasNext();) {
704 Configuration configuration = (Configuration) iterator.next();
705 Set match = findGBeanDatas(configuration, patterns);
706 datas.addAll(match);
707 }
708 return datas;
709 }
710
711 private LinkedHashSet findGBeanDatas(Configuration configuration, Set patterns) {
712 LinkedHashSet result = new LinkedHashSet();
713
714 Set gbeanNames = configuration.getGBeans().entrySet();
715 for (Iterator abstractNameQueries = patterns.iterator(); abstractNameQueries.hasNext();) {
716 AbstractNameQuery abstractNameQuery = (AbstractNameQuery) abstractNameQueries.next();
717 Artifact queryArtifact = abstractNameQuery.getArtifact();
718
719
720 if (queryArtifact == null || queryArtifact.matches(configuration.getId())) {
721
722
723 for (Iterator iterator = gbeanNames.iterator(); iterator.hasNext();) {
724 Map.Entry entry = (Map.Entry) iterator.next();
725 AbstractName abstractName = (AbstractName) entry.getKey();
726 GBeanData gbeanData = (GBeanData) entry.getValue();
727 if (abstractNameQuery.matches(abstractName, gbeanData.getGBeanInfo().getInterfaces())) {
728 result.add(gbeanData);
729 }
730 }
731 }
732 }
733 return result;
734 }
735
736 public void doStart() throws Exception {
737 log.debug("Started configuration " + id);
738 }
739
740 public synchronized void doStop() throws Exception {
741 log.debug("Stopping configuration " + id);
742 shutdown();
743
744 }
745
746 public void doFail() {
747 log.debug("Failed configuration " + id);
748 shutdown();
749 }
750
751 private void shutdown() {
752 for (Iterator iterator = children.iterator(); iterator.hasNext();) {
753 Configuration configuration = (Configuration) iterator.next();
754 configuration.shutdown();
755 }
756
757
758 gbeans.clear();
759
760
761 if (configurationClassLoader != null) {
762 configurationClassLoader.destroy();
763 }
764 }
765
766 public static final GBeanInfo GBEAN_INFO;
767
768 static {
769 GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(Configuration.class);
770 infoFactory.addReference("Parents", Configuration.class);
771 infoFactory.addAttribute("configurationData", ConfigurationData.class, true, false);
772 infoFactory.addAttribute("configurationResolver", ConfigurationResolver.class, true);
773 infoFactory.addAttribute("managedAttributeStore", ManageableAttributeStore.class, true);
774
775 infoFactory.addInterface(Configuration.class);
776
777 infoFactory.setConstructor(new String[]{
778 "Parents",
779 "configurationData",
780 "configurationResolver",
781 "managedAttributeStore"
782 });
783
784 GBEAN_INFO = infoFactory.getBeanInfo();
785 }
786
787 public static GBeanInfo getGBeanInfo() {
788 return GBEAN_INFO;
789 }
790 }