blob: 76b7e54399b66a18b1e98d84ca7d8315e146aade [file] [log] [blame]
/*
* Licensed to the Apache Software Foundation (ASF) under one or more
* contributor license agreements. See the NOTICE file distributed with
* this work for additional information regarding copyright ownership.
* The ASF licenses this file to You under the Apache License, Version 2.0
* (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*
*/
package org.apache.ivy.plugins.resolver;
import java.io.File;
import java.io.IOException;
import java.text.ParseException;
import java.util.Arrays;
import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.id.ModuleRevisionId;
import org.apache.ivy.core.report.ArtifactDownloadReport;
import org.apache.ivy.core.report.DownloadReport;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.util.Message;
/**
* DualResolver is used to resolve dependencies with one dependency revolver, called ivy resolver,
* and then download artifacts found in the resolved dependencies from a second dependency resolver,
* called artifact resolver. It is especially useful with resolvers using repository where there is
* a lot of artifact, but no ivy file, like the maven ibiblio repository. If no ivy file is found by
* the ivy resolver, the artifact resolver is used to check if there is artifact corresponding to
* the request (with default ivy file). For artifact download, however, only the artifact resolver
* is used. Exactly two resolvers should be added to this resolver for it to work properly. The
* first resolver added if the ivy resolver, the second is the artifact one.
*/
public class DualResolver extends AbstractResolver {
public static final String DESCRIPTOR_OPTIONAL = "optional";
public static final String DESCRIPTOR_REQUIRED = "required";
private DependencyResolver ivyResolver;
private DependencyResolver artifactResolver;
private boolean allownomd = true;
public void add(DependencyResolver resolver) {
if (ivyResolver == null) {
ivyResolver = resolver;
} else if (artifactResolver == null) {
artifactResolver = resolver;
} else {
throw new IllegalStateException(
"exactly two resolvers must be added: ivy(1) and artifact(2) one");
}
}
public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data)
throws ParseException {
if (ivyResolver == null || artifactResolver == null) {
throw new IllegalStateException(
"exactly two resolvers must be added: ivy(1) and artifact(2) one");
}
ResolvedModuleRevision resolved = data.getCurrentResolvedModuleRevision();
data = new ResolveData(data, doValidate(data));
final ResolvedModuleRevision mr = ivyResolver.getDependency(dd, data);
if (mr == null) {
checkInterrupted();
if (isAllownomd()) {
Message.verbose("ivy resolver didn't find " + dd
+ ": trying with artifact resolver");
return artifactResolver.getDependency(dd, data);
} else {
return null;
}
} else {
if (mr == resolved) {
// nothing has actually been resolved here, we don't need to touch the returned rmr
return mr;
}
return new ResolvedModuleRevision(mr.getResolver(), this, mr.getDescriptor(),
mr.getReport(), mr.isForce());
}
}
public ResolvedResource findIvyFileRef(DependencyDescriptor dd, ResolveData data) {
return ivyResolver.findIvyFileRef(dd, data);
}
public void reportFailure() {
ivyResolver.reportFailure();
artifactResolver.reportFailure();
}
public void reportFailure(Artifact art) {
ivyResolver.reportFailure(art);
artifactResolver.reportFailure(art);
}
public DownloadReport download(Artifact[] artifacts, DownloadOptions options) {
return artifactResolver.download(artifacts, options);
}
public DependencyResolver getArtifactResolver() {
return artifactResolver;
}
public void setArtifactResolver(DependencyResolver artifactResolver) {
this.artifactResolver = artifactResolver;
}
public DependencyResolver getIvyResolver() {
return ivyResolver;
}
public void setIvyResolver(DependencyResolver ivyResolver) {
this.ivyResolver = ivyResolver;
}
public void publish(Artifact artifact, File src, boolean overwrite) throws IOException {
if ("ivy".equals(artifact.getType())) {
ivyResolver.publish(artifact, src, overwrite);
} else {
artifactResolver.publish(artifact, src, overwrite);
}
}
@Override
public void abortPublishTransaction() throws IOException {
ivyResolver.abortPublishTransaction();
artifactResolver.abortPublishTransaction();
}
@Override
public void beginPublishTransaction(ModuleRevisionId module, boolean overwrite)
throws IOException {
ivyResolver.beginPublishTransaction(module, overwrite);
artifactResolver.beginPublishTransaction(module, overwrite);
}
@Override
public void commitPublishTransaction() throws IOException {
ivyResolver.commitPublishTransaction();
artifactResolver.commitPublishTransaction();
}
@Override
public void dumpSettings() {
if (ivyResolver == null || artifactResolver == null) {
throw new IllegalStateException(
"exactly two resolvers must be added: ivy(1) and artifact(2) one");
}
Message.verbose("\t" + getName() + " [dual " + ivyResolver.getName() + " "
+ artifactResolver.getName() + "]");
}
@Override
public boolean exists(Artifact artifact) {
if (artifact.isMetadata()) {
return ivyResolver.exists(artifact);
} else {
return artifactResolver.exists(artifact);
}
}
@Override
public ArtifactOrigin locate(Artifact artifact) {
if (artifact.isMetadata()) {
return ivyResolver.locate(artifact);
} else {
return artifactResolver.locate(artifact);
}
}
@Override
public ArtifactDownloadReport download(ArtifactOrigin artifact, DownloadOptions options) {
if (artifact.getArtifact().isMetadata()) {
return ivyResolver.download(artifact, options);
} else {
return artifactResolver.download(artifact, options);
}
}
public boolean isAllownomd() {
return allownomd;
}
public void setAllownomd(boolean allownomd) {
Message.deprecated("allownomd is deprecated, please use descriptor=\""
+ (allownomd ? DESCRIPTOR_OPTIONAL : DESCRIPTOR_REQUIRED) + "\" instead");
this.allownomd = allownomd;
}
/**
* Sets the module descriptor presence rule. Should be one of {@link #DESCRIPTOR_REQUIRED} or
* {@link #DESCRIPTOR_OPTIONAL}.
*
* @param descriptorRule
* the descriptor rule to use with this resolver.
*/
public void setDescriptor(String descriptorRule) {
if (DESCRIPTOR_REQUIRED.equals(descriptorRule)) {
allownomd = false;
} else if (DESCRIPTOR_OPTIONAL.equals(descriptorRule)) {
allownomd = true;
} else {
throw new IllegalArgumentException("unknown descriptor rule '" + descriptorRule
+ "'. Allowed rules are: "
+ Arrays.asList(new String[] {DESCRIPTOR_REQUIRED, DESCRIPTOR_OPTIONAL}));
}
}
}