001: /**
002: * Licensed to the Apache Software Foundation (ASF) under one or more
003: * contributor license agreements. See the NOTICE file distributed with
004: * this work for additional information regarding copyright ownership.
005: * The ASF licenses this file to You under the Apache License, Version 2.0
006: * (the "License"); you may not use this file except in compliance with
007: * the License. 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: */package org.apache.geronimo.kernel.config;
017:
018: import java.io.File;
019: import java.net.MalformedURLException;
020: import java.net.URL;
021: import java.util.ArrayList;
022: import java.util.Collection;
023: import java.util.Collections;
024: import java.util.LinkedHashSet;
025: import java.util.List;
026: import java.util.Set;
027: import java.util.Stack;
028:
029: import org.apache.geronimo.kernel.repository.Artifact;
030: import org.apache.geronimo.kernel.repository.ArtifactResolver;
031: import org.apache.geronimo.kernel.repository.Dependency;
032: import org.apache.geronimo.kernel.repository.ImportType;
033: import org.apache.geronimo.kernel.repository.MissingDependencyException;
034: import org.apache.geronimo.kernel.repository.Repository;
035:
036: /**
037: * @version $Rev: 581510 $ $Date: 2007-10-02 23:59:48 -0700 (Tue, 02 Oct 2007) $
038: */
039: public class ConfigurationResolver {
040: private final Artifact configurationId;
041: private final ArtifactResolver artifactResolver;
042: private final Collection<? extends Repository> 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)
057: throw new NullPointerException("configurationId is null");
058:
059: this .configurationId = configurationId;
060: this .baseDir = baseDir;
061: artifactResolver = null;
062: repositories = Collections.emptySet();
063: configurationStore = null;
064: moduleName = null;
065: }
066:
067: public ConfigurationResolver(ConfigurationData configurationData,
068: Collection<? extends Repository> repositories,
069: ArtifactResolver artifactResolver) {
070: if (configurationData == null)
071: throw new NullPointerException("configurationData is null");
072: if (repositories == null)
073: repositories = Collections.emptySet();
074:
075: configurationId = configurationData.getId();
076: this .artifactResolver = artifactResolver;
077: this .repositories = repositories;
078: configurationStore = configurationData.getConfigurationStore();
079: if (null != configurationData.getInPlaceConfigurationDir()) {
080: baseDir = configurationData.getInPlaceConfigurationDir();
081: } else {
082: baseDir = configurationData.getConfigurationDir();
083: }
084: moduleName = null;
085: }
086:
087: private ConfigurationResolver(Artifact configurationId,
088: ArtifactResolver artifactResolver,
089: Collection<? extends Repository> repositories,
090: File baseDir, ConfigurationStore configurationStore,
091: String moduleName) {
092: this .configurationId = configurationId;
093: this .artifactResolver = artifactResolver;
094: this .repositories = repositories;
095: this .baseDir = baseDir;
096: this .configurationStore = configurationStore;
097: this .moduleName = moduleName;
098: }
099:
100: public ConfigurationResolver createChildResolver(String moduleName) {
101: if (moduleName == null)
102: throw new NullPointerException("moduleName is null");
103: if (this .moduleName != null) {
104: moduleName = this .moduleName + '/' + moduleName;
105: }
106:
107: File childBaseDir = null;
108: if (baseDir != null) {
109: childBaseDir = new File(baseDir, moduleName);
110: }
111: return new ConfigurationResolver(configurationId,
112: artifactResolver, repositories, childBaseDir,
113: configurationStore, moduleName);
114: }
115:
116: public File resolve(Artifact artifact)
117: throws MissingDependencyException {
118: for (Repository repository : repositories) {
119: if (repository.contains(artifact)) {
120: File file = repository.getLocation(artifact);
121: return file;
122: }
123: }
124: throw new MissingDependencyException(artifact);
125: }
126:
127: public Set<URL> resolve(String pattern)
128: throws MalformedURLException, NoSuchConfigException {
129: if (configurationStore != null) {
130: Set<URL> matches = configurationStore.resolve(
131: configurationId, moduleName, pattern);
132: return matches;
133: } else if (baseDir != null) {
134: Set<URL> matches = IOUtil.search(baseDir, pattern);
135: return matches;
136: } else {
137: throw new IllegalStateException(
138: "No configurationStore or baseDir supplied so paths can not be resolved");
139: }
140: }
141:
142: public List<Dependency> resolveTransitiveDependencies(
143: Collection<Configuration> parents,
144: List<Dependency> dependencies)
145: throws MissingDependencyException {
146: Stack<Artifact> parentStack = new Stack<Artifact>();
147: return internalResolveTransitiveDependencies(parents,
148: dependencies, parentStack);
149: }
150:
151: private List<Dependency> internalResolveTransitiveDependencies(
152: Collection<Configuration> parents,
153: List<Dependency> dependencies, Stack<Artifact> parentStack)
154: throws MissingDependencyException {
155: List<Dependency> resolvedDependencies = new ArrayList<Dependency>();
156: for (Dependency dependency1 : dependencies) {
157: Dependency dependency = resolveDependency(parents,
158: dependency1, parentStack);
159:
160: if (!resolvedDependencies.contains(dependency)) {
161: resolvedDependencies.add(dependency);
162:
163: List<Dependency> childDependencies = getChildDependencies(dependency);
164: if (!childDependencies.isEmpty()) {
165: parentStack.push(dependency.getArtifact());
166: childDependencies = internalResolveTransitiveDependencies(
167: parents, childDependencies, parentStack);
168: parentStack.pop();
169: resolvedDependencies.addAll(childDependencies);
170: }
171: }
172: }
173: return resolvedDependencies;
174: }
175:
176: private Dependency resolveDependency(
177: Collection<Configuration> parents, Dependency dependency,
178: Stack<Artifact> parentStack)
179: throws MissingDependencyException {
180: Artifact artifact = dependency.getArtifact();
181:
182: // we might need an artifact resolver at this point
183: if (artifactResolver == null) {
184: // if it is already resolved we are done
185: if (artifact.isResolved()) {
186: return dependency;
187: }
188: throw new MissingDependencyException(
189: "Artifact is not resolved and there no artifact resolver available: ",
190: artifact, parentStack);
191: }
192:
193: // resolve the artifact
194: try {
195: artifact = artifactResolver.resolveInClassLoader(artifact,
196: parents);
197: } catch (MissingDependencyException e) {
198: e.setQuery(artifact);
199: e.setStack(parentStack);
200: throw e;
201: }
202:
203: // build a new dependency object to contain the resolved artifact
204: Dependency resolvedDependency = new Dependency(artifact,
205: dependency.getImportType());
206: return resolvedDependency;
207: }
208:
209: private ArrayList<Dependency> getChildDependencies(
210: Dependency dependency) {
211: ArrayList<Dependency> childDependencies = new ArrayList<Dependency>();
212: for (Repository repository : repositories) {
213: if (repository.contains(dependency.getArtifact())) {
214: // get the child artifacts
215: LinkedHashSet<Artifact> childArtifacts = repository
216: .getDependencies(dependency.getArtifact());
217: for (Artifact artifact : childArtifacts) {
218: // add each child as a classes-only dependency
219: childDependencies.add(new Dependency(artifact,
220: ImportType.CLASSES));
221: }
222: }
223: }
224: return childDependencies;
225: }
226: }
|