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 }