View Javadoc

1   /**
2    *
3    * Copyright 2005 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  package org.apache.geronimo.kernel.config;
18  
19  import java.util.List;
20  import java.util.Collection;
21  import java.util.ArrayList;
22  import java.util.Iterator;
23  import java.util.LinkedHashSet;
24  import java.util.Collections;
25  import java.util.Set;
26  import java.io.File;
27  import java.net.MalformedURLException;
28  
29  import org.apache.geronimo.kernel.repository.ArtifactResolver;
30  import org.apache.geronimo.kernel.repository.MissingDependencyException;
31  import org.apache.geronimo.kernel.repository.Dependency;
32  import org.apache.geronimo.kernel.repository.Artifact;
33  import org.apache.geronimo.kernel.repository.Repository;
34  import org.apache.geronimo.kernel.repository.ImportType;
35  
36  /**
37   * @version $Rev: 410741 $ $Date: 2006-05-31 21:35:48 -0700 (Wed, 31 May 2006) $
38   */
39  public class ConfigurationResolver {
40      private final Artifact configurationId;
41      private final ArtifactResolver artifactResolver;
42      private final Collection repositories;
43  
44      /**
45       * file or configstore used to resolve classpath parts
46       */
47      private final File baseDir;
48      private final ConfigurationStore configurationStore;
49  
50      /**
51       * For nested configurations, the module name will be non-null.
52       */
53      private final String moduleName;
54  
55      public ConfigurationResolver(Artifact configurationId, File baseDir) {
56          if (configurationId == null)  throw new NullPointerException("configurationId is null");
57  
58          this.configurationId = configurationId;
59          this.baseDir = baseDir;
60          artifactResolver = null;
61          repositories = Collections.EMPTY_SET;
62          configurationStore = null;
63          moduleName = null;
64      }
65  
66      public ConfigurationResolver(ConfigurationData configurationData, Collection repositories, ArtifactResolver artifactResolver) {
67          if (configurationData == null)  throw new NullPointerException("configurationData is null");
68          if (repositories == null) repositories = Collections.EMPTY_SET;
69  
70          configurationId = configurationData.getId();
71          this.artifactResolver = artifactResolver;
72          this.repositories = repositories;
73          configurationStore = configurationData.getConfigurationStore();
74          if (null != configurationData.getInPlaceConfigurationDir()) {
75              baseDir = configurationData.getInPlaceConfigurationDir();
76          } else {
77              baseDir = configurationData.getConfigurationDir();
78          }
79          moduleName = null;
80      }
81  
82      private ConfigurationResolver(Artifact configurationId, ArtifactResolver artifactResolver, Collection repositories, File baseDir, ConfigurationStore configurationStore, String moduleName) {
83          this.configurationId = configurationId;
84          this.artifactResolver = artifactResolver;
85          this.repositories = repositories;
86          this.baseDir = baseDir;
87          this.configurationStore = configurationStore;
88          this.moduleName = moduleName;
89      }
90  
91      public ConfigurationResolver createChildResolver(String moduleName) {
92          if (moduleName == null) throw new NullPointerException("moduleName is null");
93          if (this.moduleName != null) {
94              moduleName = this.moduleName + '/' + moduleName;
95          }
96  
97          File childBaseDir = null;
98          if (baseDir != null) {
99              childBaseDir = new File(baseDir, moduleName);
100         }
101         return new ConfigurationResolver(configurationId, artifactResolver, repositories, childBaseDir, configurationStore, moduleName);
102     }
103 
104     public File resolve(Artifact artifact) throws MissingDependencyException {
105         for (Iterator j = repositories.iterator(); j.hasNext();) {
106             Repository repository = (Repository) j.next();
107             if (repository.contains(artifact)) {
108                 File file = repository.getLocation(artifact);
109                 return file;
110             }
111         }
112         throw new MissingDependencyException("Unable to resolve dependency " + artifact);
113     }
114 
115     public Set resolve(String pattern) throws MalformedURLException, NoSuchConfigException {
116         if (configurationStore != null) {
117             Set matches = configurationStore.resolve(configurationId, moduleName, pattern);
118             return matches;
119         } else if (baseDir != null) {
120             Set matches = IOUtil.search(baseDir, pattern);
121             return matches;
122         } else {
123             throw new IllegalStateException("No configurationStore or baseDir supplied so paths can not be resolved");
124         }
125     }
126 
127     public List resolveTransitiveDependencies(Collection parents, List dependencies) throws MissingDependencyException {
128         List resolvedDependencies = new ArrayList();
129         for (Iterator iterator = dependencies.iterator(); iterator.hasNext();) {
130             Dependency dependency = resolveDependency(parents, (Dependency) iterator.next());
131 
132             if (!resolvedDependencies.contains(dependency)) {
133                 resolvedDependencies.add(dependency);
134 
135                 List childDependencies = getChildDependencies(dependency);
136                 if (!childDependencies.isEmpty()) {
137                     childDependencies = resolveTransitiveDependencies(parents, childDependencies);
138                     resolvedDependencies.addAll(childDependencies);
139                 }
140             }
141         }
142         return resolvedDependencies;
143     }
144 
145     private Dependency resolveDependency(Collection parents, Dependency dependency) throws MissingDependencyException {
146         Artifact artifact = dependency.getArtifact();
147 
148         // if it is already resolved we are done
149         if (artifact.isResolved()) {
150             return dependency;
151         }
152 
153         // we need an artifact resolver at this point
154         if (artifactResolver == null) {
155             throw new MissingDependencyException("Artifact is not resolved and there no artifact resolver available: " + artifact);
156         }
157 
158         // resolve the artifact
159         artifact = artifactResolver.resolveInClassLoader(artifact, parents);
160 
161         // build a new dependency object to contain the resolved artifact
162         Dependency resolvedDependency = new Dependency(artifact, dependency.getImportType());
163         return resolvedDependency;
164     }
165 
166     private ArrayList getChildDependencies(Dependency dependency) {
167         ArrayList childDependencies = new ArrayList();
168         for (Iterator repositoryIterator = repositories.iterator(); repositoryIterator.hasNext();) {
169             Repository repository = (Repository) repositoryIterator.next();
170             if (repository.contains(dependency.getArtifact())) {
171                 // get the child artifacts
172                 LinkedHashSet childArtifacts = repository.getDependencies(dependency.getArtifact());
173                 for (Iterator artifactIterator = childArtifacts.iterator(); artifactIterator.hasNext();) {
174                     Artifact artifact = (Artifact) artifactIterator.next();
175                     // add each child as a classes-only dependency
176                     childDependencies.add(new Dependency(artifact,  ImportType.CLASSES));
177                 }
178             }
179         }
180         return childDependencies;
181     }
182 }