KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > org > apache > geronimo > kernel > config > Configuration


1 /**
2  * Licensed to the Apache Software Foundation (ASF) under one or more
3  * contributor license agreements. See the NOTICE file distributed with
4  * this work for additional information regarding copyright ownership.
5  * The ASF licenses this file to You under the Apache License, Version 2.0
6  * (the "License"); you may not use this file except in compliance with
7  * the License. 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 JavaDoc;
21 import java.io.IOException JavaDoc;
22 import java.net.MalformedURLException JavaDoc;
23 import java.net.URL JavaDoc;
24 import java.util.ArrayList JavaDoc;
25 import java.util.Collection JavaDoc;
26 import java.util.Collections JavaDoc;
27 import java.util.HashMap JavaDoc;
28 import java.util.Iterator JavaDoc;
29 import java.util.LinkedHashSet JavaDoc;
30 import java.util.List JavaDoc;
31 import java.util.ListIterator JavaDoc;
32 import java.util.Map JavaDoc;
33 import java.util.Set JavaDoc;
34 import java.util.HashSet JavaDoc;
35
36 import javax.management.MalformedObjectNameException JavaDoc;
37 import javax.management.ObjectName JavaDoc;
38
39 import org.apache.commons.logging.Log;
40 import org.apache.commons.logging.LogFactory;
41 import org.apache.geronimo.gbean.AbstractName;
42 import org.apache.geronimo.gbean.AbstractNameQuery;
43 import org.apache.geronimo.gbean.GBeanData;
44 import org.apache.geronimo.gbean.GBeanInfo;
45 import org.apache.geronimo.gbean.GBeanInfoBuilder;
46 import org.apache.geronimo.gbean.GBeanLifecycle;
47 import org.apache.geronimo.gbean.ReferencePatterns;
48 import org.apache.geronimo.kernel.GBeanAlreadyExistsException;
49 import org.apache.geronimo.kernel.GBeanNotFoundException;
50 import org.apache.geronimo.kernel.Naming;
51 import org.apache.geronimo.kernel.classloader.JarFileClassLoader;
52 import org.apache.geronimo.kernel.repository.Artifact;
53 import org.apache.geronimo.kernel.repository.Dependency;
54 import org.apache.geronimo.kernel.repository.Environment;
55 import org.apache.geronimo.kernel.repository.ImportType;
56 import org.apache.geronimo.kernel.repository.MissingDependencyException;
57
58 /**
59  * A Configuration represents a collection of runnable services that can be
60  * loaded into a Geronimo Kernel and brought online. The primary components in
61  * a Configuration are a codebase, represented by a collection of URLs that
62  * is used to locate classes, and a collection of GBean instances that define
63  * its state.
64  * <p/>
65  * The persistent attributes of the Configuration are:
66  * <ul>
67  * <li>its unique configId used to identify this specific config</li>
68  * <li>the configId of a parent Configuration on which this one is dependent</li>
69  * <li>a List<URI> of code locations (which may be absolute or relative to a baseURL)</li>
70  * <li>a byte[] holding the state of the GBeans instances in Serialized form</li>
71  * </ul>
72  * When a configuration is started, it converts the URIs into a set of absolute
73  * URLs by resolving them against the specified baseURL (this would typically
74  * be the root of the CAR file which contains the configuration) and then
75  * constructs a ClassLoader for that codebase. That ClassLoader is then used
76  * to de-serialize the persisted GBeans, ensuring the GBeans can be recycled
77  * as necessary. Once the GBeans have been restored, they are brought online
78  * by registering them with the MBeanServer.
79  * <p/>
80  * A dependency on the Configuration is created for every GBean it loads. As a
81  * result, a startRecursive() operation on the configuration will result in
82  * a startRecursive() for all the GBeans it contains. Similarly, if the
83  * Configuration is stopped then all of its GBeans will be stopped as well.
84  *
85  * @version $Rev:385718 $ $Date: 2006-12-01 19:53:00 -0500 (Fri, 01 Dec 2006) $
86  */

87 public class Configuration implements GBeanLifecycle, ConfigurationParent {
88     private static final Log log = LogFactory.getLog(Configuration.class);
89
90     /**
91      * Converts an Artifact to an AbstractName for a configuration. Does not
92      * validate that this is a reasonable or resolved Artifact, or that it
93      * corresponds to an actual Configuration.
94      */

95     public static AbstractName getConfigurationAbstractName(Artifact configId) throws InvalidConfigException {
96         return new AbstractName(configId, Collections.singletonMap("configurationName", configId.toString()), getConfigurationObjectName(configId));
97     }
98
99     public static boolean isConfigurationObjectName(ObjectName JavaDoc name) {
100         return name.getDomain().equals("geronimo.config") && name.getKeyPropertyList().size() == 1 && name.getKeyProperty("name") != null;
101     }
102
103     public static Artifact getConfigurationID(ObjectName JavaDoc objectName) {
104         if (isConfigurationObjectName(objectName)) {
105             String JavaDoc name = ObjectName.unquote(objectName.getKeyProperty("name"));
106             return Artifact.create(name);
107         } else {
108             throw new IllegalArgumentException JavaDoc("ObjectName " + objectName + " is not a Configuration name");
109         }
110     }
111
112     private static ObjectName JavaDoc getConfigurationObjectName(Artifact configId) throws InvalidConfigException {
113         try {
114             return new ObjectName JavaDoc("geronimo.config:name=" + ObjectName.quote(configId.toString()));
115         } catch (MalformedObjectNameException JavaDoc e) {
116             throw new InvalidConfigException("Could not construct object name for configuration", e);
117         }
118     }
119
120     /**
121      * The artifact id for this configuration.
122      */

123     private final Artifact id;
124
125     /**
126      * The registered abstractName for this configuraion.
127      */

128     private final AbstractName abstractName;
129
130     /**
131      * Defines the environment requred for this configuration.
132      */

133     private final Environment environment;
134
135     /**
136      * Used to resolve dependecies and paths
137      */

138     private final ConfigurationResolver configurationResolver;
139
140     /**
141      * Parent configurations used for class loader.
142      */

143     private final List JavaDoc classParents = new ArrayList JavaDoc();
144
145     /**
146      * Parent configuations used for service resolution.
147      */

148     private final List JavaDoc serviceParents = new ArrayList JavaDoc();
149
150     /**
151      * All service parents depth first
152      */

153     private final List JavaDoc allServiceParents = new ArrayList JavaDoc();
154
155     /**
156      * Artifacts added to the class loader (non-configuation artifacts).
157      */

158     private final LinkedHashSet JavaDoc dependencies = new LinkedHashSet JavaDoc();
159
160     /**
161      * The GBeanData objects by ObjectName
162      */

163     private final Map JavaDoc gbeans = new HashMap JavaDoc();
164
165     /**
166      * The classloader used to load the child GBeans contained in this configuration.
167      */

168     private final MultiParentClassLoader configurationClassLoader;
169
170     /**
171      * The relative class path (URI) of this configuation.
172      */

173     private final LinkedHashSet JavaDoc classPath;
174
175     /**
176      * Naming system used when generating a name for a new gbean
177      */

178     private final Naming naming;
179
180     /**
181      * Environment, classpath, gbeans and other data for this configuration.
182      */

183     private ConfigurationData configurationData;
184
185     /**
186      * The nested configurations of this configuration.
187      */

188     List JavaDoc children = new ArrayList JavaDoc();
189
190     /**
191      * The parent of this configuration;
192      */

193     private Configuration parent = null;
194
195     /**
196      * Only used to allow declaration as a reference.
197      */

198     public Configuration() {
199         id = null;
200         abstractName = null;
201         environment = null;
202         classPath = null;
203         configurationResolver = null;
204         configurationClassLoader = null;
205         naming = null;
206     }
207
208     /**
209      * Creates a configuration.
210      * @param parents parents of this configuation (not ordered)
211      * @param configurationData the module type, environment and classpath of the configuration
212      * @param configurationResolver used to resolve dependecies and paths
213      */

214     public Configuration(Collection JavaDoc parents,
215             ConfigurationData configurationData,
216             ConfigurationResolver configurationResolver,
217             ManageableAttributeStore attributeStore) throws MissingDependencyException, MalformedURLException JavaDoc, NoSuchConfigException, InvalidConfigException {
218         if (parents == null) parents = Collections.EMPTY_SET;
219         if (configurationData == null) throw new NullPointerException JavaDoc("configurationData is null");
220         if (configurationResolver == null) throw new NullPointerException JavaDoc("configurationResolver is null");
221
222         this.configurationData = configurationData;
223         this.environment = configurationData.getEnvironment();
224         this.configurationResolver = configurationResolver;
225         this.classPath = new LinkedHashSet JavaDoc(configurationData.getClassPath());
226         this.naming = configurationData.getNaming();
227
228         this.id = environment.getConfigId();
229         abstractName = getConfigurationAbstractName(id);
230
231         //
232
// Transitively resolve all the dependencies in the environment
233
//
234
List JavaDoc transtiveDependencies = configurationResolver.resolveTransitiveDependencies(parents, environment.getDependencies());
235
236         //
237
// Process transtive dependencies splitting it into classParents, serviceParents and artifactDependencies
238
//
239
Map JavaDoc parentsById = new HashMap JavaDoc();
240         for (Iterator JavaDoc iterator = parents.iterator(); iterator.hasNext();) {
241             Configuration configuration = (Configuration) iterator.next();
242             Artifact id = configuration.getId();
243             parentsById.put(id, configuration);
244         }
245
246         for (Iterator JavaDoc iterator = transtiveDependencies.iterator(); iterator.hasNext();) {
247             Dependency dependency = (Dependency) iterator.next();
248             Artifact artifact = dependency.getArtifact();
249             if (parentsById.containsKey(artifact)) {
250                 Configuration parent = (Configuration) parentsById.get(artifact);
251                 if (dependency.getImportType() == ImportType.CLASSES || dependency.getImportType() == ImportType.ALL) {
252                     classParents.add(parent);
253                 }
254                 if (dependency.getImportType() == ImportType.SERVICES || dependency.getImportType() == ImportType.ALL) {
255                     serviceParents.add(parent);
256                 }
257             } else if (dependency.getImportType() == ImportType.SERVICES) {
258                 throw new IllegalStateException JavaDoc("Could not find parent " + artifact + " in the parents collection");
259             } else {
260                 dependencies.add(artifact);
261             }
262         }
263
264         try {
265             //
266
// Build the configuration class loader
267
//
268
configurationClassLoader = createConfigurationClasssLoader(parents, environment, classPath);
269
270             //
271
// Get all service parents in depth first order
272
//
273

274             addDepthFirstServiceParents(this, allServiceParents, new HashSet JavaDoc());
275
276             //
277
// Deserialize the GBeans in the configurationData
278
//
279
Collection JavaDoc gbeans = configurationData.getGBeans(configurationClassLoader);
280             if (attributeStore != null) {
281                 gbeans = attributeStore.applyOverrides(id, gbeans, configurationClassLoader);
282             }
283             for (Iterator JavaDoc iterator = gbeans.iterator(); iterator.hasNext();) {
284                 GBeanData gbeanData = (GBeanData) iterator.next();
285                 this.gbeans.put(gbeanData.getAbstractName(), gbeanData);
286             }
287
288             //
289
// Create child configurations
290
//
291
LinkedHashSet JavaDoc childParents = new LinkedHashSet JavaDoc(parents);
292             childParents.add(this);
293             for (Iterator JavaDoc iterator = configurationData.getChildConfigurations().entrySet().iterator(); iterator.hasNext();) {
294                 Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
295                 String JavaDoc moduleName = (String JavaDoc) entry.getKey();
296                 ConfigurationData childConfigurationData = (ConfigurationData) entry.getValue();
297                 Configuration childConfiguration = new Configuration(childParents, childConfigurationData, configurationResolver.createChildResolver(moduleName), attributeStore);
298                 childConfiguration.parent = this;
299                 children.add(childConfiguration);
300             }
301         } catch (RuntimeException JavaDoc e) {
302             shutdown();
303             throw e;
304         } catch (Error JavaDoc e) {
305             shutdown();
306             throw e;
307         } catch (MissingDependencyException e) {
308             shutdown();
309             throw e;
310         } catch (MalformedURLException JavaDoc e) {
311             shutdown();
312             throw e;
313         } catch (NoSuchConfigException e) {
314             shutdown();
315             throw e;
316         } catch (InvalidConfigException e) {
317             shutdown();
318             throw e;
319         }
320     }
321
322     private MultiParentClassLoader createConfigurationClasssLoader(Collection JavaDoc parents, Environment environment, LinkedHashSet JavaDoc classPath) throws MalformedURLException JavaDoc, MissingDependencyException, NoSuchConfigException {
323         // create the URL list
324
URL JavaDoc[] urls = buildClassPath(classPath);
325
326         // parents
327
ClassLoader JavaDoc[] parentClassLoaders;
328         if (parents.size() == 0 && classParents.size() == 0) {
329             // no explicit parent set, so use the class loader of this class as
330
// the parent... this class should be in the root geronimo classloader,
331
// which is normally the system class loader but not always, so be safe
332
parentClassLoaders = new ClassLoader JavaDoc[] {getClass().getClassLoader()};
333         } else {
334             parentClassLoaders = new ClassLoader JavaDoc[classParents.size()];
335             for (ListIterator JavaDoc iterator = classParents.listIterator(); iterator.hasNext();) {
336                 Configuration configuration = (Configuration) iterator.next();
337                 parentClassLoaders[iterator.previousIndex()] = configuration.getConfigurationClassLoader();
338             }
339         }
340
341         // hidden classes
342
Set JavaDoc hiddenClassesSet = environment.getHiddenClasses();
343         String JavaDoc[] hiddenClasses = (String JavaDoc[]) hiddenClassesSet.toArray(new String JavaDoc[hiddenClassesSet.size()]);
344
345         // we need to propagate the non-overrideable classes from parents
346
LinkedHashSet JavaDoc nonOverridableSet = new LinkedHashSet JavaDoc();
347         for (Iterator JavaDoc iterator = classParents.iterator(); iterator.hasNext();) {
348             Configuration parent = (Configuration) iterator.next();
349
350             Environment parentEnvironment = parent.getEnvironment();
351             nonOverridableSet.addAll(parentEnvironment.getNonOverrideableClasses());
352         }
353         String JavaDoc[] nonOverridableClasses = (String JavaDoc[]) nonOverridableSet.toArray(new String JavaDoc[nonOverridableSet.size()]);
354
355         if (log.isDebugEnabled()) {
356             StringBuffer JavaDoc buf = new StringBuffer JavaDoc("ClassLoader structure for configuration ").append(id).append("\n");
357             buf.append("Parent configurations:\n");
358             for (Iterator JavaDoc iterator = classParents.iterator(); iterator.hasNext();) {
359                 Configuration configuration = (Configuration) iterator.next();
360                 buf.append(" ").append(configuration.getId()).append("\n");
361             }
362             buf.append("ClassPath:\n");
363             for (int i = 0; i < urls.length; i++) {
364                 URL JavaDoc url = urls[i];
365                 buf.append(" ").append(url).append("\n");
366             }
367             log.debug(buf.toString());
368         }
369
370         if (Boolean.getBoolean("Xorg.apache.geronimo.OldClassLoader")) {
371             return new MultiParentClassLoader(environment.getConfigId(),
372                     urls,
373                     parentClassLoaders,
374                     environment.isInverseClassLoading(),
375                     hiddenClasses,
376                     nonOverridableClasses);
377         } else {
378             return new JarFileClassLoader(environment.getConfigId(),
379                     urls,
380                     parentClassLoaders,
381                     environment.isInverseClassLoading(),
382                     hiddenClasses,
383                     nonOverridableClasses);
384         }
385     }
386
387     private void addDepthFirstServiceParents(Configuration configuration, List JavaDoc ancestors, Set JavaDoc ids) {
388         if (!ids.contains(configuration.getId())) {
389             ancestors.add(configuration);
390             ids.add(configuration.getId());
391             for (Iterator JavaDoc parents = configuration.getServiceParents().iterator(); parents.hasNext();) {
392                 Configuration parent = (Configuration) parents.next();
393                 addDepthFirstServiceParents(parent, ancestors, ids);
394             }
395         }
396     }
397
398     private URL JavaDoc[] buildClassPath(LinkedHashSet JavaDoc classPath) throws MalformedURLException JavaDoc, MissingDependencyException, NoSuchConfigException {
399         List JavaDoc urls = new ArrayList JavaDoc();
400         for (Iterator JavaDoc i = dependencies.iterator(); i.hasNext();) {
401             Artifact artifact = (Artifact) i.next();
402             File JavaDoc file = configurationResolver.resolve(artifact);
403             urls.add(file.toURL());
404         }
405         if (classPath != null) {
406             for (Iterator JavaDoc i = classPath.iterator(); i.hasNext();) {
407                 String JavaDoc pattern = (String JavaDoc) i.next();
408                 Set JavaDoc matches = configurationResolver.resolve(pattern);
409                 for (Iterator JavaDoc iterator = matches.iterator(); iterator.hasNext();) {
410                     URL JavaDoc url = (URL JavaDoc) iterator.next();
411                     urls.add(url);
412                 }
413             }
414         }
415         return (URL JavaDoc[]) urls.toArray(new URL JavaDoc[urls.size()]);
416     }
417
418     /**
419      * Return the unique Id
420      * @return the unique Id
421      */

422     public Artifact getId() {
423         return id;
424     }
425
426     /**
427      * Gets the unique name of this configuration within the kernel.
428      * @return the unique name of this configuration
429      */

430     public String JavaDoc getObjectName() {
431         try {
432             return getConfigurationObjectName(id).getCanonicalName();
433         } catch (InvalidConfigException e) {
434             throw new AssertionError JavaDoc(e);
435         }
436     }
437
438     public AbstractName getAbstractName() {
439         return abstractName;
440     }
441
442     /**
443      * Gets the parent configurations used for class loading.
444      * @return the parents of this configuration used for class loading
445      */

446     public List JavaDoc getClassParents() {
447         return classParents;
448     }
449
450     /**
451      * Gets the parent configurations used for service resolution.
452      * @return the parents of this configuration used for service resolution
453      */

454     public List JavaDoc getServiceParents() {
455         return serviceParents;
456     }
457
458     /**
459      * Gets the artifact dependencies of this configuration.
460      * @return the artifact dependencies of this configuration
461      */

462     public LinkedHashSet JavaDoc getDependencies() {
463         return dependencies;
464     }
465
466     /**
467      * Gets the declaration of the environment in which this configuration runs.
468      * @return the environment of this configuration
469      */

470     public Environment getEnvironment() {
471         return environment;
472     }
473
474     /**
475      * This is used by the configuration manager to restart an existing configuation.
476      * Do not modify the configuation data.
477      * @return the configuation data for this configuration; do not modify
478      */

479     ConfigurationData getConfigurationData() {
480         return configurationData;
481     }
482
483     /**
484      * @deprecated this is only exposed temporarily for configuration manager
485      */

486     public ConfigurationResolver getConfigurationResolver() {
487         return configurationResolver;
488     }
489
490     /**
491      * Gets the relative class path (URIs) of this configuration.
492      * @return the relative class path of this configuation
493      */

494     public List JavaDoc getClassPath() {
495         return new ArrayList JavaDoc(classPath);
496     }
497
498     public void addToClassPath(String JavaDoc pattern) throws IOException JavaDoc {
499         if (!classPath.contains(pattern)) {
500             try {
501                 Set JavaDoc matches = configurationResolver.resolve(pattern);
502                 for (Iterator JavaDoc iterator = matches.iterator(); iterator.hasNext();) {
503                     URL JavaDoc url = (URL JavaDoc) iterator.next();
504                     configurationClassLoader.addURL(url);
505                 }
506                 classPath.add(pattern);
507             } catch (Exception JavaDoc e) {
508                 throw new IOException JavaDoc("Unable to extend classpath with " + pattern);
509             }
510         }
511     }
512
513     /**
514      * Gets the type of the configuration (WAR, RAR et cetera)
515      * @return Type of the configuration.
516      */

517     public ConfigurationModuleType getModuleType() {
518         return configurationData.getModuleType();
519     }
520
521     /**
522      * Gets the time at which this configuration was created (or deployed).
523      * @return the time at which this configuration was created (or deployed)
524      */

525     public long getCreated() {
526         return configurationData.getCreated();
527     }
528
529     /**
530      * Gets the class loader for this configuration.
531      * @return the class loader for this configuration
532      */

533     public ClassLoader JavaDoc getConfigurationClassLoader() {
534         return configurationClassLoader;
535     }
536
537     /**
538      * Gets the nested configurations of this configuration. That is, the
539      * configurations within this one as a WAR can be within an EAR; not
540      * including wholly separate configurations that just depend on this
541      * one as a parent.
542      *
543      * @return the nested configuration of this configuration
544      */

545     public List JavaDoc getChildren() {
546         return Collections.unmodifiableList(children);
547     }
548
549     /**
550      * Gets the configurations owned by this configuration. This is only used for cascade-uninstall.
551      * @return the configurations owned by this configuration
552      */

553     public Set JavaDoc getOwnedConfigurations() {
554         return configurationData.getOwnedConfigurations();
555     }
556
557     /**
558      * Gets an unmodifiable collection of the GBeanDatas for the GBeans in this configuration.
559      * @return the GBeans in this configuration
560      */

561     public Map JavaDoc getGBeans() {
562         return Collections.unmodifiableMap(gbeans);
563     }
564
565     /**
566      * Determines of this configuration constains the specified GBean.
567      * @param gbean the name of the GBean
568      * @return true if this configuration contains the specified GBean; false otherwise
569      */

570     public synchronized boolean containsGBean(AbstractName gbean) {
571         return gbeans.containsKey(gbean);
572     }
573
574     /**
575      * Gets the enclosing configuration of this one (e.g. the EAR for a WAR),
576      * or null if it has none.
577      */

578     public Configuration getEnclosingConfiguration() {
579         return parent;
580     }
581
582     public synchronized AbstractName addGBean(String JavaDoc name, GBeanData gbean) throws GBeanAlreadyExistsException {
583         AbstractName abstractName = gbean.getAbstractName();
584         if (abstractName != null) {
585             throw new IllegalArgumentException JavaDoc("gbean already has an abstract name: " + abstractName);
586         }
587
588         String JavaDoc j2eeType = gbean.getGBeanInfo().getJ2eeType();
589         if (j2eeType == null) j2eeType = "GBean";
590         abstractName = naming.createRootName(id, name, j2eeType);
591         gbean.setAbstractName(abstractName);
592
593         if (gbeans.containsKey(abstractName)) {
594             throw new GBeanAlreadyExistsException(gbean.getAbstractName().toString());
595         }
596         gbeans.put(abstractName, gbean);
597         return abstractName;
598     }
599
600     public synchronized void addGBean(GBeanData gbean) throws GBeanAlreadyExistsException {
601         if (gbeans.containsKey(gbean.getAbstractName())) {
602             throw new GBeanAlreadyExistsException(gbean.getAbstractName().toString());
603         }
604         gbeans.put(gbean.getAbstractName(), gbean);
605     }
606
607     public synchronized void removeGBean(AbstractName name) throws GBeanNotFoundException {
608         if (!gbeans.containsKey(name)) {
609             throw new GBeanNotFoundException(name);
610         }
611         gbeans.remove(name);
612     }
613
614     public AbstractName findGBean(AbstractNameQuery pattern) throws GBeanNotFoundException {
615         if (pattern == null) throw new NullPointerException JavaDoc("pattern is null");
616         return findGBean(Collections.singleton(pattern));
617     }
618
619     public GBeanData findGBeanData(AbstractNameQuery pattern) throws GBeanNotFoundException {
620         if (pattern == null) throw new NullPointerException JavaDoc("pattern is null");
621         return findGBeanData(Collections.singleton(pattern));
622     }
623
624     public AbstractName findGBean(ReferencePatterns referencePatterns) throws GBeanNotFoundException {
625         if (referencePatterns == null) throw new NullPointerException JavaDoc("referencePatterns is null");
626         if (referencePatterns.isResolved()) {
627             return referencePatterns.getAbstractName();
628         }
629
630         // check the local config
631
Set JavaDoc patterns = referencePatterns.getPatterns();
632         return findGBean(patterns);
633     }
634
635     public AbstractName findGBean(Set JavaDoc patterns) throws GBeanNotFoundException {
636         if (patterns == null) throw new NullPointerException JavaDoc("patterns is null");
637         return findGBeanData(patterns).getAbstractName();
638     }
639
640     public GBeanData findGBeanData(Set JavaDoc patterns) throws GBeanNotFoundException {
641         if (patterns == null) throw new NullPointerException JavaDoc("patterns is null");
642         Set JavaDoc result = findGBeanDatas(this, patterns);
643         if (result.size() > 1) {
644             throw new GBeanNotFoundException("More than one match to referencePatterns", patterns);
645         } else if (result.size() == 1) {
646             return (GBeanData) result.iterator().next();
647         }
648
649         // search all parents
650
for (Iterator JavaDoc iterator = allServiceParents.iterator(); iterator.hasNext();) {
651             Configuration configuration = (Configuration) iterator.next();
652             result.addAll(findGBeanDatas(configuration, patterns));
653
654             // if we already found a match we have an ambiguous query
655
if (result.size() > 1) {
656                 List JavaDoc names = new ArrayList JavaDoc(result.size());
657                 for (Iterator JavaDoc iterator1 = result.iterator(); iterator1.hasNext();) {
658                     GBeanData gBeanData = (GBeanData) iterator1.next();
659                     names.add(gBeanData.getAbstractName());
660                 }
661                 throw new GBeanNotFoundException("More than one match to referencePatterns: " + names.toString(), patterns);
662             }
663         }
664
665         if (result.isEmpty()) {
666             throw new GBeanNotFoundException("No matches for referencePatterns", patterns);
667         }
668
669         return (GBeanData) result.iterator().next();
670     }
671
672     public LinkedHashSet JavaDoc findGBeans(AbstractNameQuery pattern) {
673         if (pattern == null) throw new NullPointerException JavaDoc("pattern is null");
674         return findGBeans(Collections.singleton(pattern));
675     }
676
677     public LinkedHashSet JavaDoc findGBeans(ReferencePatterns referencePatterns) {
678         if (referencePatterns == null) throw new NullPointerException JavaDoc("referencePatterns is null");
679         if (referencePatterns.getAbstractName() != null) {
680             // this pattern is already resolved
681
LinkedHashSet JavaDoc result = new LinkedHashSet JavaDoc();
682             result.add(referencePatterns.getAbstractName());
683             return result;
684         }
685
686         // check the local config
687
Set JavaDoc patterns = referencePatterns.getPatterns();
688         return findGBeans(patterns);
689     }
690
691     public LinkedHashSet JavaDoc findGBeans(Set JavaDoc patterns) {
692         if (patterns == null) throw new NullPointerException JavaDoc("patterns is null");
693         LinkedHashSet JavaDoc datas = findGBeanDatas(patterns);
694         LinkedHashSet JavaDoc result = new LinkedHashSet JavaDoc(datas.size());
695         for (Iterator JavaDoc iterator = datas.iterator(); iterator.hasNext();) {
696             GBeanData gBeanData = (GBeanData) iterator.next();
697             result.add(gBeanData.getAbstractName());
698         }
699
700         return result;
701     }
702
703     public LinkedHashSet JavaDoc findGBeanDatas(Set JavaDoc patterns) {
704         if (patterns == null) throw new NullPointerException JavaDoc("patterns is null");
705         LinkedHashSet JavaDoc datas = findGBeanDatas(this, patterns);
706
707         // search all parents
708
for (Iterator JavaDoc iterator = allServiceParents.iterator(); iterator.hasNext();) {
709             Configuration configuration = (Configuration) iterator.next();
710             Set JavaDoc match = findGBeanDatas(configuration, patterns);
711             datas.addAll(match);
712         }
713         return datas;
714     }
715
716     /**
717      * Find the gbeanDatas matching the patterns in this configuration only, ignoring parents.
718      *
719      * @param configuration
720      * @param patterns
721      * @return set of gbeandatas matching one of the patterns from this configuration only, not including parents.
722      */

723     private LinkedHashSet JavaDoc findGBeanDatas(Configuration configuration, Set JavaDoc patterns) {
724         LinkedHashSet JavaDoc result = new LinkedHashSet JavaDoc();
725
726         Set JavaDoc gbeanNames = configuration.getGBeans().entrySet();
727         for (Iterator JavaDoc abstractNameQueries = patterns.iterator(); abstractNameQueries.hasNext();) {
728             AbstractNameQuery abstractNameQuery = (AbstractNameQuery) abstractNameQueries.next();
729             Artifact queryArtifact = abstractNameQuery.getArtifact();
730
731             // Does this query apply to this configuration
732
if (queryArtifact == null || queryArtifact.matches(configuration.getId())) {
733
734                 // Search the GBeans
735
for (Iterator JavaDoc iterator = gbeanNames.iterator(); iterator.hasNext();) {
736                     Map.Entry JavaDoc entry = (Map.Entry JavaDoc) iterator.next();
737                     AbstractName abstractName = (AbstractName) entry.getKey();
738                     GBeanData gbeanData = (GBeanData) entry.getValue();
739                     if (abstractNameQuery.matches(abstractName, gbeanData.getGBeanInfo().getInterfaces())) {
740                         result.add(gbeanData);
741                     }
742                 }
743             }
744         }
745         return result;
746     }
747
748     public void doStart() throws Exception JavaDoc {
749         log.debug("Started configuration " + id);
750     }
751
752     public synchronized void doStop() throws Exception JavaDoc {
753         log.debug("Stopping configuration " + id);
754         shutdown();
755
756     }
757
758     public void doFail() {
759         log.debug("Failed configuration " + id);
760         shutdown();
761     }
762
763     private void shutdown() {
764         for (Iterator JavaDoc iterator = children.iterator(); iterator.hasNext();) {
765             Configuration configuration = (Configuration) iterator.next();
766             configuration.shutdown();
767         }
768
769         // clear references to GBeanDatas
770
gbeans.clear();
771
772         // destroy the class loader
773
if (configurationClassLoader != null) {
774             configurationClassLoader.destroy();
775         }
776     }
777
778     public static final GBeanInfo GBEAN_INFO;
779
780     static {
781         GBeanInfoBuilder infoFactory = GBeanInfoBuilder.createStatic(Configuration.class);//does not use jsr-77 naming
782
infoFactory.addReference("Parents", Configuration.class);
783         infoFactory.addAttribute("configurationData", ConfigurationData.class, true, false);
784         infoFactory.addAttribute("configurationResolver", ConfigurationResolver.class, true);
785         infoFactory.addAttribute("managedAttributeStore", ManageableAttributeStore.class, true);
786
787         infoFactory.addInterface(Configuration.class);
788
789         infoFactory.setConstructor(new String JavaDoc[]{
790                 "Parents",
791                 "configurationData",
792                 "configurationResolver",
793                 "managedAttributeStore"
794         });
795
796         GBEAN_INFO = infoFactory.getBeanInfo();
797     }
798
799     public static GBeanInfo getGBeanInfo() {
800         return GBEAN_INFO;
801     }
802 }
803
Popular Tags