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.util.List;
020 import java.util.Collection;
021 import java.util.ArrayList;
022 import java.util.Iterator;
023 import java.util.LinkedHashSet;
024 import java.util.Collections;
025 import java.util.Set;
026 import java.io.File;
027 import java.net.MalformedURLException;
028
029 import org.apache.geronimo.kernel.repository.ArtifactResolver;
030 import org.apache.geronimo.kernel.repository.MissingDependencyException;
031 import org.apache.geronimo.kernel.repository.Dependency;
032 import org.apache.geronimo.kernel.repository.Artifact;
033 import org.apache.geronimo.kernel.repository.Repository;
034 import org.apache.geronimo.kernel.repository.ImportType;
035
036 /**
037 * @version $Rev: 410741 $ $Date: 2006-05-31 21:35:48 -0700 (Wed, 31 May 2006) $
038 */
039 public class ConfigurationResolver {
040 private final Artifact configurationId;
041 private final ArtifactResolver artifactResolver;
042 private final Collection repositories;
043
044 /**
045 * file or configstore used to resolve classpath parts
046 */
047 private final File baseDir;
048 private final ConfigurationStore configurationStore;
049
050 /**
051 * For nested configurations, the module name will be non-null.
052 */
053 private final String moduleName;
054
055 public ConfigurationResolver(Artifact configurationId, File baseDir) {
056 if (configurationId == null) throw new NullPointerException("configurationId is null");
057
058 this.configurationId = configurationId;
059 this.baseDir = baseDir;
060 artifactResolver = null;
061 repositories = Collections.EMPTY_SET;
062 configurationStore = null;
063 moduleName = null;
064 }
065
066 public ConfigurationResolver(ConfigurationData configurationData, Collection repositories, ArtifactResolver artifactResolver) {
067 if (configurationData == null) throw new NullPointerException("configurationData is null");
068 if (repositories == null) repositories = Collections.EMPTY_SET;
069
070 configurationId = configurationData.getId();
071 this.artifactResolver = artifactResolver;
072 this.repositories = repositories;
073 configurationStore = configurationData.getConfigurationStore();
074 if (null != configurationData.getInPlaceConfigurationDir()) {
075 baseDir = configurationData.getInPlaceConfigurationDir();
076 } else {
077 baseDir = configurationData.getConfigurationDir();
078 }
079 moduleName = null;
080 }
081
082 private ConfigurationResolver(Artifact configurationId, ArtifactResolver artifactResolver, Collection repositories, File baseDir, ConfigurationStore configurationStore, String moduleName) {
083 this.configurationId = configurationId;
084 this.artifactResolver = artifactResolver;
085 this.repositories = repositories;
086 this.baseDir = baseDir;
087 this.configurationStore = configurationStore;
088 this.moduleName = moduleName;
089 }
090
091 public ConfigurationResolver createChildResolver(String moduleName) {
092 if (moduleName == null) throw new NullPointerException("moduleName is null");
093 if (this.moduleName != null) {
094 moduleName = this.moduleName + '/' + moduleName;
095 }
096
097 File childBaseDir = null;
098 if (baseDir != null) {
099 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 }