All Downloads are FREE. Search and download functionalities are using the official Maven repository.

org.apache.ivy.plugins.resolver.BasicResolver Maven / Gradle / Ivy

There is a newer version: 2.5.2
Show newest version
/*
 *  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.FileInputStream;
import java.io.IOException;
import java.net.URL;
import java.text.ParseException;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.Date;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.ListIterator;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.ivy.core.IvyContext;
import org.apache.ivy.core.IvyPatternHelper;
import org.apache.ivy.core.LogOptions;
import org.apache.ivy.core.cache.ArtifactOrigin;
import org.apache.ivy.core.cache.ModuleDescriptorWriter;
import org.apache.ivy.core.cache.RepositoryCacheManager;
import org.apache.ivy.core.module.descriptor.Artifact;
import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor;
import org.apache.ivy.core.module.descriptor.DependencyDescriptor;
import org.apache.ivy.core.module.descriptor.ModuleDescriptor;
import org.apache.ivy.core.module.id.ModuleId;
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.report.DownloadStatus;
import org.apache.ivy.core.report.MetadataArtifactDownloadReport;
import org.apache.ivy.core.resolve.DownloadOptions;
import org.apache.ivy.core.resolve.IvyNode;
import org.apache.ivy.core.resolve.ResolveData;
import org.apache.ivy.core.resolve.ResolvedModuleRevision;
import org.apache.ivy.core.search.ModuleEntry;
import org.apache.ivy.core.search.OrganisationEntry;
import org.apache.ivy.core.search.RevisionEntry;
import org.apache.ivy.plugins.parser.ModuleDescriptorParser;
import org.apache.ivy.plugins.parser.ModuleDescriptorParserRegistry;
import org.apache.ivy.plugins.parser.xml.XmlModuleDescriptorWriter;
import org.apache.ivy.plugins.repository.ArtifactResourceResolver;
import org.apache.ivy.plugins.repository.Resource;
import org.apache.ivy.plugins.repository.ResourceDownloader;
import org.apache.ivy.plugins.repository.file.FileRepository;
import org.apache.ivy.plugins.repository.file.FileResource;
import org.apache.ivy.plugins.repository.url.URLRepository;
import org.apache.ivy.plugins.repository.url.URLResource;
import org.apache.ivy.plugins.resolver.util.MDResolvedResource;
import org.apache.ivy.plugins.resolver.util.ResolvedResource;
import org.apache.ivy.plugins.resolver.util.ResourceMDParser;
import org.apache.ivy.util.Checks;
import org.apache.ivy.util.ChecksumHelper;
import org.apache.ivy.util.HostUtil;
import org.apache.ivy.util.Message;

/**
 *
 */
public abstract class BasicResolver extends AbstractResolver {
    public static final String DESCRIPTOR_OPTIONAL = "optional";

    public static final String DESCRIPTOR_REQUIRED = "required";
    
    /**
     * Exception thrown internally in getDependency to indicate a dependency is unresolved.
     * 

* Due to the contract of getDependency, this exception is never thrown publicly, but rather * converted in a message (either error or verbose) and returning null *

*/ private static class UnresolvedDependencyException extends RuntimeException { private boolean error; /** * Dependency has not been resolved. * This is not an error and won't log any message. */ public UnresolvedDependencyException() { this("", false); } /** * Dependency has not been resolved. * This is an error and will log a message. */ public UnresolvedDependencyException(String message) { this(message, true); } /** * Dependency has not been resolved. * The boolean tells if it is an error or not, a message will be logged if non empty. */ public UnresolvedDependencyException(String message, boolean error) { super(message); this.error = error; } public boolean isError() { return error; } } public static final SimpleDateFormat DATE_FORMAT = new SimpleDateFormat("yyyyMMddHHmmss"); private String workspaceName; /** * True if the files resolved are dependent of the environment from which they have been * resolved, false otherwise. In general, relative paths are dependent of the environment, and * absolute paths including machine reference are not. */ private boolean envDependent = true; private List ivyattempts = new ArrayList(); private Map artattempts = new HashMap(); private boolean checkconsistency = true; private boolean allownomd = true; private boolean force = false; private String checksums = null; private URLRepository extartifactrep = new URLRepository(); // used only to download // external artifacts public BasicResolver() { workspaceName = HostUtil.getLocalHostName(); } public String getWorkspaceName() { return workspaceName; } public void setWorkspaceName(String workspaceName) { this.workspaceName = workspaceName; } public boolean isEnvDependent() { return envDependent; } public void setEnvDependent(boolean envDependent) { this.envDependent = envDependent; } public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data) throws ParseException { IvyContext context = IvyContext.pushNewCopyContext(); try { ResolvedModuleRevision mr = data.getCurrentResolvedModuleRevision(); if (mr != null) { if (shouldReturnResolvedModule(dd, mr)) { return mr; } } if (isForce()) { dd = dd.clone(ModuleRevisionId.newInstance( dd.getDependencyRevisionId(), "latest.integration")); } DependencyDescriptor systemDd = dd; DependencyDescriptor nsDd = fromSystem(dd); context.setDependencyDescriptor(systemDd); context.setResolveData(data); clearIvyAttempts(); clearArtifactAttempts(); ModuleRevisionId systemMrid = systemDd.getDependencyRevisionId(); ModuleRevisionId nsMrid = nsDd.getDependencyRevisionId(); checkRevision(systemMrid); boolean isDynamic = getAndCheckIsDynamic(systemMrid); // we first search for the dependency in cache ResolvedModuleRevision rmr = null; rmr = findModuleInCache(systemDd, data); if (rmr != null) { if (rmr.getDescriptor().isDefault() && rmr.getResolver() != this) { Message.verbose("\t" + getName() + ": found revision in cache: " + systemMrid + " (resolved by " + rmr.getResolver().getName() + "): but it's a default one, maybe we can find a better one"); } else if (isForce() && rmr.getResolver() != this) { Message.verbose("\t" + getName() + ": found revision in cache: " + systemMrid + " (resolved by " + rmr.getResolver().getName() + "): but we are in force mode, let's try to find one ourself"); } else { Message.verbose("\t" + getName() + ": revision in cache: " + systemMrid); return checkLatest(checkForcedResolvedModuleRevision(rmr), data); } } checkInterrupted(); ResolvedResource ivyRef = findIvyFileRef(nsDd, data); checkInterrupted(); // get module descriptor ModuleDescriptor nsMd; ModuleDescriptor systemMd = null; if (ivyRef == null) { if (!isAllownomd()) { throw new UnresolvedDependencyException( "\t" + getName() + ": no ivy file found for " + systemMrid, false); } nsMd = DefaultModuleDescriptor.newDefaultInstance(nsMrid, nsDd .getAllDependencyArtifacts()); ResolvedResource artifactRef = findFirstArtifactRef(nsMd, nsDd, data); checkInterrupted(); if (artifactRef == null) { throw new UnresolvedDependencyException("\t" + getName() + ": no ivy file nor artifact found for " + systemMrid, false); } else { long lastModified = artifactRef.getLastModified(); if (lastModified != 0 && nsMd instanceof DefaultModuleDescriptor) { ((DefaultModuleDescriptor) nsMd).setLastModified(lastModified); } Message.verbose("\t" + getName() + ": no ivy file found for " + systemMrid + ": using default data"); if (isDynamic) { nsMd.setResolvedModuleRevisionId(ModuleRevisionId.newInstance(nsMrid, artifactRef.getRevision())); } systemMd = toSystem(nsMd); MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(systemMd.getMetadataArtifact()); madr.setDownloadStatus(DownloadStatus.NO); madr.setSearched(true); rmr = new ResolvedModuleRevision(this, this, systemMd, madr, isForce()); } } else { if (ivyRef instanceof MDResolvedResource) { rmr = ((MDResolvedResource) ivyRef).getResolvedModuleRevision(); } if (rmr == null) { rmr = parse(ivyRef, systemDd, data); if (rmr == null) { throw new UnresolvedDependencyException(); } } if (!rmr.getReport().isDownloaded() && rmr.getReport().getLocalFile() != null) { return checkLatest(checkForcedResolvedModuleRevision(rmr), data); } else { nsMd = rmr.getDescriptor(); // check descriptor data is in sync with resource revision and names systemMd = toSystem(nsMd); if (isCheckconsistency()) { checkDescriptorConsistency(systemMrid, systemMd, ivyRef); checkDescriptorConsistency(nsMrid, nsMd, ivyRef); } else { if (systemMd instanceof DefaultModuleDescriptor) { DefaultModuleDescriptor defaultMd = (DefaultModuleDescriptor) systemMd; ModuleRevisionId revision = getRevision(ivyRef, systemMrid, systemMd); defaultMd.setModuleRevisionId(revision); defaultMd.setResolvedModuleRevisionId(revision); } else { Message.warn( "consistency disabled with instance of non DefaultModuleDescriptor..." + " module info can't be updated, so consistency check will be done"); checkDescriptorConsistency(nsMrid, nsMd, ivyRef); checkDescriptorConsistency(systemMrid, systemMd, ivyRef); } } rmr = new ResolvedModuleRevision( this, this, systemMd, toSystem(rmr.getReport()), isForce()); } } resolveAndCheckRevision(systemMd, systemMrid, ivyRef, isDynamic); resolveAndCheckPublicationDate(systemDd, systemMd, systemMrid, data); checkNotConvertedExclusionRule(systemMd, ivyRef, data); cacheModuleDescriptor(systemMd, systemMrid, ivyRef, rmr); return checkLatest(checkForcedResolvedModuleRevision(rmr), data); } catch (UnresolvedDependencyException ex) { if (ex.getMessage().length() > 0) { if (ex.isError()) { Message.error(ex.getMessage()); } else { Message.verbose(ex.getMessage()); } } return data.getCurrentResolvedModuleRevision(); } finally { IvyContext.popContext(); } } protected boolean shouldReturnResolvedModule( DependencyDescriptor dd, ResolvedModuleRevision mr) { // a resolved module revision has already been found by a prior dependency resolver // let's see if it should be returned and bypass this resolver ModuleRevisionId mrid = dd.getDependencyRevisionId(); boolean isDynamic = getSettings().getVersionMatcher().isDynamic(mrid); boolean shouldReturn = mr.isForce(); shouldReturn |= !isDynamic && !mr.getDescriptor().isDefault(); shouldReturn &= !isForce(); return shouldReturn; } private ResolvedModuleRevision checkForcedResolvedModuleRevision(ResolvedModuleRevision rmr) { if (rmr == null) { return null; } if (!isForce() || rmr.isForce()) { return rmr; } return new ResolvedModuleRevision( rmr.getResolver(), rmr.getArtifactResolver(), rmr.getDescriptor(), rmr.getReport(), true); } private void cacheModuleDescriptor(ModuleDescriptor systemMd, ModuleRevisionId systemMrid, ResolvedResource ivyRef, ResolvedModuleRevision rmr) { RepositoryCacheManager cacheManager = getRepositoryCacheManager(); final ModuleDescriptorParser parser = systemMd.getParser(); // the metadata artifact which was used to cache the original metadata file Artifact requestedMetadataArtifact = ivyRef == null ? systemMd.getMetadataArtifact() : parser.getMetadataArtifact( ModuleRevisionId.newInstance(systemMrid, ivyRef.getRevision()), ivyRef.getResource()); cacheManager.originalToCachedModuleDescriptor(this, ivyRef, requestedMetadataArtifact, rmr, new ModuleDescriptorWriter() { public void write(ResolvedResource originalMdResource, ModuleDescriptor md, File src, File dest) throws IOException, ParseException { if (originalMdResource == null) { // a basic ivy file is written containing default data XmlModuleDescriptorWriter.write(md, dest); } else { // copy and update ivy file from source to cache parser.toIvyFile( new FileInputStream(src), originalMdResource.getResource(), dest, md); long repLastModified = originalMdResource.getLastModified(); if (repLastModified > 0) { dest.setLastModified(repLastModified); } } } }); } private void checkNotConvertedExclusionRule(ModuleDescriptor systemMd, ResolvedResource ivyRef, ResolveData data) { if (!systemMd.isDefault() && data.getSettings().logNotConvertedExclusionRule() && systemMd instanceof DefaultModuleDescriptor) { DefaultModuleDescriptor dmd = (DefaultModuleDescriptor) systemMd; if (dmd.isNamespaceUseful()) { Message.warn( "the module descriptor " + ivyRef.getResource() + " has information which can't be converted into " + "the system namespace. " + "It will require the availability of the namespace '" + getNamespace().getName() + "' to be fully usable."); } } } private void resolveAndCheckPublicationDate(DependencyDescriptor systemDd, ModuleDescriptor systemMd, ModuleRevisionId systemMrid, ResolveData data) { // resolve and check publication date if (data.getDate() != null) { long pubDate = getPublicationDate(systemMd, systemDd, data); if (pubDate > data.getDate().getTime()) { throw new UnresolvedDependencyException( "\t" + getName() + ": unacceptable publication date => was=" + new Date(pubDate) + " required=" + data.getDate()); } else if (pubDate == -1) { throw new UnresolvedDependencyException("\t" + getName() + ": impossible to guess publication date: artifact missing for " + systemMrid); } systemMd.setResolvedPublicationDate(new Date(pubDate)); } } private void checkModuleDescriptorRevision(ModuleDescriptor systemMd, ModuleRevisionId systemMrid) { if (!getSettings().getVersionMatcher().accept(systemMrid, systemMd)) { throw new UnresolvedDependencyException( "\t" + getName() + ": unacceptable revision => was=" + systemMd.getResolvedModuleRevisionId().getRevision() + " required=" + systemMrid.getRevision()); } } private boolean getAndCheckIsDynamic(ModuleRevisionId systemMrid) { boolean isDynamic = getSettings().getVersionMatcher().isDynamic(systemMrid); if (isDynamic && !acceptLatest()) { throw new UnresolvedDependencyException( "dynamic revisions not handled by " + getClass().getName() + ". impossible to resolve " + systemMrid); } return isDynamic; } private void checkRevision(ModuleRevisionId systemMrid) { // check revision int index = systemMrid.getRevision().indexOf("@"); if (index != -1 && !systemMrid.getRevision().substring(index + 1).equals(workspaceName)) { throw new UnresolvedDependencyException("\t" + getName() + ": unhandled revision => " + systemMrid.getRevision()); } } private void resolveAndCheckRevision(ModuleDescriptor systemMd, ModuleRevisionId dependencyConstraint, ResolvedResource ivyRef, boolean isDynamic) { // we get the resolved module revision id from the descriptor: it may contain extra // attributes that were not included in the dependency constraint ModuleRevisionId resolvedMrid = systemMd.getResolvedModuleRevisionId(); if (resolvedMrid.getRevision() == null || resolvedMrid.getRevision().length() == 0 || resolvedMrid.getRevision().startsWith("working@")) { if (!isDynamic) { resolvedMrid = ModuleRevisionId.newInstance( resolvedMrid, dependencyConstraint.getRevision()); } else if (ivyRef == null) { resolvedMrid = systemMd.getMetadataArtifact().getModuleRevisionId(); } else if (ivyRef.getRevision() == null || ivyRef.getRevision().length() == 0) { resolvedMrid = ModuleRevisionId.newInstance(resolvedMrid, "working@" + getName()); } else { resolvedMrid = ModuleRevisionId.newInstance(resolvedMrid, ivyRef .getRevision()); } } if (isDynamic) { Message.verbose("\t\t[" + toSystem(resolvedMrid).getRevision() + "] " + dependencyConstraint.getModuleId()); } systemMd.setResolvedModuleRevisionId(resolvedMrid); checkModuleDescriptorRevision(systemMd, dependencyConstraint); } private ModuleRevisionId getRevision(ResolvedResource ivyRef, ModuleRevisionId askedMrid, ModuleDescriptor md) throws ParseException { Map allAttributes = new HashMap(); allAttributes.putAll(md.getQualifiedExtraAttributes()); allAttributes.putAll(askedMrid.getQualifiedExtraAttributes()); String revision = ivyRef.getRevision(); if (revision == null) { Message.debug("no revision found in reference for " + askedMrid); if (getSettings().getVersionMatcher().isDynamic(askedMrid)) { if (md.getModuleRevisionId().getRevision() == null) { revision = "working@" + getName(); } else { Message.debug("using " + askedMrid); revision = askedMrid.getRevision(); } } else { Message.debug("using " + askedMrid); revision = askedMrid.getRevision(); } } return ModuleRevisionId.newInstance(askedMrid.getOrganisation(), askedMrid.getName(), askedMrid.getBranch(), revision, allAttributes); } public ResolvedModuleRevision parse(final ResolvedResource mdRef, DependencyDescriptor dd, ResolveData data) throws ParseException { DependencyDescriptor nsDd = dd; dd = toSystem(nsDd); ModuleRevisionId mrid = dd.getDependencyRevisionId(); ModuleDescriptorParser parser = ModuleDescriptorParserRegistry .getInstance().getParser(mdRef.getResource()); if (parser == null) { Message.warn("no module descriptor parser available for " + mdRef.getResource()); return null; } Message.verbose("\t" + getName() + ": found md file for " + mrid); Message.verbose("\t\t=> " + mdRef); Message.debug("\tparser = " + parser); ModuleRevisionId resolvedMrid = mrid; // first check if this dependency has not yet been resolved if (getSettings().getVersionMatcher().isDynamic(mrid)) { resolvedMrid = ModuleRevisionId.newInstance(mrid, mdRef.getRevision()); IvyNode node = data.getNode(resolvedMrid); if (node != null && node.getModuleRevision() != null) { // this revision has already be resolved : return it if (node.getDescriptor() != null && node.getDescriptor().isDefault()) { Message.verbose("\t" + getName() + ": found already resolved revision: " + resolvedMrid + ": but it's a default one, maybe we can find a better one"); } else { Message.verbose("\t" + getName() + ": revision already resolved: " + resolvedMrid); node.getModuleRevision().getReport().setSearched(true); return node.getModuleRevision(); } } } Artifact moduleArtifact = parser.getMetadataArtifact(resolvedMrid, mdRef.getResource()); return getRepositoryCacheManager().cacheModuleDescriptor( this, mdRef, dd, moduleArtifact, downloader, getCacheOptions(data)); } protected ResourceMDParser getRMDParser(final DependencyDescriptor dd, final ResolveData data) { return new ResourceMDParser() { public MDResolvedResource parse(Resource resource, String rev) { try { ResolvedModuleRevision rmr = BasicResolver.this.parse(new ResolvedResource( resource, rev), dd, data); if (rmr == null) { return null; } else { return new MDResolvedResource(resource, rev, rmr); } } catch (ParseException e) { Message.warn("Failed to parse the file '" + resource + "': " + e.getMessage()); return null; } } }; } protected ResourceMDParser getDefaultRMDParser(final ModuleId mid) { return new ResourceMDParser() { public MDResolvedResource parse(Resource resource, String rev) { DefaultModuleDescriptor md = DefaultModuleDescriptor.newDefaultInstance(new ModuleRevisionId(mid, rev)); MetadataArtifactDownloadReport madr = new MetadataArtifactDownloadReport(md.getMetadataArtifact()); madr.setDownloadStatus(DownloadStatus.NO); madr.setSearched(true); return new MDResolvedResource(resource, rev, new ResolvedModuleRevision( BasicResolver.this, BasicResolver.this, md, madr, isForce())); } }; } // private boolean isResolved(ResolveData data, ModuleRevisionId mrid) { // IvyNode node = getSystemNode(data, mrid); // return node != null && node.getModuleRevision() != null; // } // private void checkDescriptorConsistency(ModuleRevisionId mrid, ModuleDescriptor md, ResolvedResource ivyRef) throws ParseException { boolean ok = true; StringBuffer errors = new StringBuffer(); if (!mrid.getOrganisation().equals(md.getModuleRevisionId().getOrganisation())) { Message.error("\t" + getName() + ": bad organisation found in " + ivyRef.getResource() + ": expected='" + mrid.getOrganisation() + "' found='" + md.getModuleRevisionId().getOrganisation() + "'"); errors.append("bad organisation: expected='" + mrid.getOrganisation() + "' found='" + md.getModuleRevisionId().getOrganisation() + "'; "); ok = false; } if (!mrid.getName().equals(md.getModuleRevisionId().getName())) { Message.error("\t" + getName() + ": bad module name found in " + ivyRef.getResource() + ": expected='" + mrid.getName() + " found='" + md.getModuleRevisionId().getName() + "'"); errors.append("bad module name: expected='" + mrid.getName() + "' found='" + md.getModuleRevisionId().getName() + "'; "); ok = false; } if (mrid.getBranch() != null && !mrid.getBranch().equals(md.getModuleRevisionId().getBranch())) { Message.error("\t" + getName() + ": bad branch name found in " + ivyRef.getResource() + ": expected='" + mrid.getBranch() + " found='" + md.getModuleRevisionId().getBranch() + "'"); errors.append("bad branch name: expected='" + mrid.getBranch() + "' found='" + md.getModuleRevisionId().getBranch() + "'; "); ok = false; } if (ivyRef.getRevision() != null && !ivyRef.getRevision().startsWith("working@")) { ModuleRevisionId expectedMrid = ModuleRevisionId .newInstance(mrid, ivyRef.getRevision()); if (!getSettings().getVersionMatcher().accept(expectedMrid, md)) { Message.error("\t" + getName() + ": bad revision found in " + ivyRef.getResource() + ": expected='" + ivyRef.getRevision() + " found='" + md.getModuleRevisionId().getRevision() + "'"); errors.append("bad revision: expected='" + ivyRef.getRevision() + "' found='" + md.getModuleRevisionId().getRevision() + "'; "); ok = false; } } if (!getSettings().getStatusManager().isStatus(md.getStatus())) { Message.error("\t" + getName() + ": bad status found in " + ivyRef.getResource() + ": '" + md.getStatus() + "'"); errors.append("bad status: '" + md.getStatus() + "'; "); ok = false; } for (Iterator it = mrid.getExtraAttributes().entrySet().iterator(); it.hasNext();) { Entry extra = (Entry) it.next(); if (extra.getValue() != null && !extra.getValue().equals( md.getExtraAttribute((String) extra.getKey()))) { String errorMsg = "bad " + extra.getKey() + " found in " + ivyRef.getResource() + ": expected='" + extra.getValue() + "' found='" + md.getExtraAttribute((String) extra.getKey()) + "'"; Message.error("\t" + getName() + ": " + errorMsg); errors.append(errorMsg + ";"); ok = false; } } if (!ok) { throw new ParseException("inconsistent module descriptor file found in '" + ivyRef.getResource() + "': " + errors, 0); } } protected void clearIvyAttempts() { ivyattempts.clear(); clearArtifactAttempts(); } protected void logIvyAttempt(String attempt) { ivyattempts.add(attempt); Message.verbose("\t\ttried " + attempt); } protected void logArtifactAttempt(Artifact art, String attempt) { List attempts = (List) artattempts.get(art); if (attempts == null) { attempts = new ArrayList(); artattempts.put(art, attempts); } attempts.add(attempt); Message.verbose("\t\ttried " + attempt); } protected void logAttempt(String attempt) { Artifact currentArtifact = (Artifact) IvyContext.getContext().get(getName() + ".artifact"); if (currentArtifact != null) { logArtifactAttempt(currentArtifact, attempt); } else { logIvyAttempt(attempt); } } public void reportFailure() { Message.warn("==== " + getName() + ": tried"); for (ListIterator iter = ivyattempts.listIterator(); iter.hasNext();) { String m = (String) iter.next(); Message.warn(" " + m); } for (Iterator iter = artattempts.keySet().iterator(); iter.hasNext();) { Artifact art = (Artifact) iter.next(); List attempts = (List) artattempts.get(art); if (attempts != null) { Message.warn(" -- artifact " + art + ":"); for (ListIterator iterator = attempts.listIterator(); iterator.hasNext();) { String m = (String) iterator.next(); Message.warn(" " + m); } } } } public void reportFailure(Artifact art) { Message.warn("==== " + getName() + ": tried"); List attempts = (List) artattempts.get(art); if (attempts != null) { for (ListIterator iter = attempts.listIterator(); iter.hasNext();) { String m = (String) iter.next(); Message.warn(" " + m); } } } protected boolean acceptLatest() { return true; } public DownloadReport download(Artifact[] artifacts, DownloadOptions options) { RepositoryCacheManager cacheManager = getRepositoryCacheManager(); clearArtifactAttempts(); DownloadReport dr = new DownloadReport(); for (int i = 0; i < artifacts.length; i++) { ArtifactDownloadReport adr = cacheManager.download( artifacts[i], artifactResourceResolver, downloader, getCacheDownloadOptions(options)); if (DownloadStatus.FAILED == adr.getDownloadStatus()) { if (!ArtifactDownloadReport.MISSING_ARTIFACT.equals(adr.getDownloadDetails())) { Message.warn("\t" + adr); } } else if (DownloadStatus.NO == adr.getDownloadStatus()) { Message.verbose("\t" + adr); } else if (LogOptions.LOG_QUIET.equals(options.getLog())) { Message.verbose("\t" + adr); } else { Message.info("\t" + adr); } dr.addArtifactReport(adr); checkInterrupted(); } return dr; } protected void clearArtifactAttempts() { artattempts.clear(); } public ArtifactDownloadReport download(final ArtifactOrigin origin, DownloadOptions options) { Checks.checkNotNull(origin, "origin"); return getRepositoryCacheManager().download( origin.getArtifact(), new ArtifactResourceResolver() { public ResolvedResource resolve(Artifact artifact) { try { Resource resource = getResource(origin.getLocation()); if (resource == null) { return null; } String revision = origin.getArtifact().getModuleRevisionId().getRevision(); return new ResolvedResource(resource, revision); } catch (IOException e) { return null; } } }, downloader, getCacheDownloadOptions(options)); } protected abstract Resource getResource(String source) throws IOException; public boolean exists(Artifact artifact) { ResolvedResource artifactRef = getArtifactRef(artifact, null); if (artifactRef != null) { return artifactRef.getResource().exists(); } return false; } public ArtifactOrigin locate(Artifact artifact) { ArtifactOrigin origin = getRepositoryCacheManager().getSavedArtifactOrigin(artifact); if (!ArtifactOrigin.isUnknown(origin)) { return origin; } ResolvedResource artifactRef = getArtifactRef(artifact, null); if (artifactRef != null && artifactRef.getResource().exists()) { return new ArtifactOrigin( artifact, artifactRef.getResource().isLocal(), artifactRef.getResource().getName()); } return null; } protected long getPublicationDate(ModuleDescriptor md, DependencyDescriptor dd, ResolveData data) { if (md.getPublicationDate() != null) { return md.getPublicationDate().getTime(); } ResolvedResource artifactRef = findFirstArtifactRef(md, dd, data); if (artifactRef != null) { return artifactRef.getLastModified(); } return -1; } public String toString() { return getName(); } public String[] listTokenValues(String token, Map otherTokenValues) { Collection ret = findNames(otherTokenValues, token); return (String[]) ret.toArray(new String[ret.size()]); } public OrganisationEntry[] listOrganisations() { Collection names = findNames(Collections.EMPTY_MAP, IvyPatternHelper.ORGANISATION_KEY); OrganisationEntry[] ret = new OrganisationEntry[names.size()]; int i = 0; for (Iterator iter = names.iterator(); iter.hasNext(); i++) { String org = (String) iter.next(); ret[i] = new OrganisationEntry(this, org); } return ret; } public ModuleEntry[] listModules(OrganisationEntry org) { Map tokenValues = new HashMap(); tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, org.getOrganisation()); Collection names = findNames(tokenValues, IvyPatternHelper.MODULE_KEY); ModuleEntry[] ret = new ModuleEntry[names.size()]; int i = 0; for (Iterator iter = names.iterator(); iter.hasNext(); i++) { String name = (String) iter.next(); ret[i] = new ModuleEntry(org, name); } return ret; } public RevisionEntry[] listRevisions(ModuleEntry mod) { Map tokenValues = new HashMap(); tokenValues.put(IvyPatternHelper.ORGANISATION_KEY, mod.getOrganisation()); tokenValues.put(IvyPatternHelper.MODULE_KEY, mod.getModule()); Collection names = findNames(tokenValues, IvyPatternHelper.REVISION_KEY); RevisionEntry[] ret = new RevisionEntry[names.size()]; int i = 0; for (Iterator iter = names.iterator(); iter.hasNext(); i++) { String name = (String) iter.next(); ret[i] = new RevisionEntry(mod, name); } return ret; } protected abstract Collection findNames(Map tokenValues, String token); protected ResolvedResource findFirstArtifactRef(ModuleDescriptor md, DependencyDescriptor dd, ResolveData data) { ResolvedResource ret = null; String[] conf = md.getConfigurationsNames(); for (int i = 0; i < conf.length; i++) { Artifact[] artifacts = md.getArtifacts(conf[i]); for (int j = 0; j < artifacts.length; j++) { ret = getArtifactRef(artifacts[j], data.getDate()); if (ret != null) { return ret; } } } return null; } protected long getAndCheck(Resource resource, File dest) throws IOException { long size = get(resource, dest); String[] checksums = getChecksumAlgorithms(); boolean checked = false; for (int i = 0; i < checksums.length && !checked; i++) { checked = check(resource, dest, checksums[i]); } return size; } /** * Checks the given resource checksum if a checksum resource exists. * * @param resource * the resource to check * @param dest * the file where the resource has been downloaded * @param algorithm * the checksum algorithm to use * @return true if the checksum has been successfully checked, false if the checksum wasn't * available * @throws IOException * if a checksum exist but do not match the downloaded file checksum */ private boolean check(Resource resource, File dest, String algorithm) throws IOException { Resource csRes = resource.clone(resource.getName() + "." + algorithm); if (csRes.exists()) { Message.debug(algorithm + " file found for " + resource + ": checking..."); File csFile = File.createTempFile("ivytmp", algorithm); try { get(csRes, csFile); try { ChecksumHelper.check(dest, csFile, algorithm); Message.verbose(algorithm + " OK for " + resource); return true; } catch (IOException ex) { dest.delete(); throw ex; } } finally { csFile.delete(); } } else { return false; } } protected ResolvedResource getArtifactRef(Artifact artifact, Date date) { IvyContext.getContext().set(getName() + ".artifact", artifact); try { ResolvedResource ret = findArtifactRef(artifact, date); if (ret == null && artifact.getUrl() != null) { URL url = artifact.getUrl(); Message.verbose("\tusing url for " + artifact + ": " + url); logArtifactAttempt(artifact, url.toExternalForm()); Resource resource; if ("file".equals(url.getProtocol())) { resource = new FileResource(new FileRepository(), new File(url.getPath())); } else { resource = new URLResource(url); } ret = new ResolvedResource(resource, artifact.getModuleRevisionId() .getRevision()); } return ret; } finally { IvyContext.getContext().set(getName() + ".artifact", null); } } protected abstract ResolvedResource findArtifactRef(Artifact artifact, Date date); protected abstract long get(Resource resource, File dest) throws IOException; public boolean isCheckconsistency() { return checkconsistency; } public void setCheckconsistency(boolean checkConsitency) { checkconsistency = checkConsitency; } public void setForce(boolean force) { this.force = force; } public boolean isForce() { return force; } public boolean isAllownomd() { return allownomd; } public void setAllownomd(boolean b) { Message.deprecated( "allownomd is deprecated, please use descriptor=\"" + (b ? DESCRIPTOR_OPTIONAL : DESCRIPTOR_REQUIRED) + "\" instead"); allownomd = b; } /** * 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})); } } public String[] getChecksumAlgorithms() { String csDef = checksums == null ? getSettings().getVariable("ivy.checksums") : checksums; if (csDef == null) { return new String[0]; } // csDef is a comma separated list of checksum algorithms to use with this resolver // we parse and return it as a String[] String[] checksums = csDef.split(","); List algos = new ArrayList(); for (int i = 0; i < checksums.length; i++) { String cs = checksums[i].trim(); if (!"".equals(cs) && !"none".equals(cs)) { algos.add(cs); } } return (String[]) algos.toArray(new String[algos.size()]); } public void setChecksums(String checksums) { this.checksums = checksums; } private final ArtifactResourceResolver artifactResourceResolver = new ArtifactResourceResolver() { public ResolvedResource resolve(Artifact artifact) { artifact = fromSystem(artifact); return getArtifactRef(artifact, null); } }; private final ResourceDownloader downloader = new ResourceDownloader() { public void download(Artifact artifact, Resource resource, File dest) throws IOException { if (dest.exists()) { dest.delete(); } File part = new File(dest.getAbsolutePath() + ".part"); if (resource.getName().equals( String.valueOf(artifact.getUrl()))) { if (part.getParentFile() != null) { part.getParentFile().mkdirs(); } extartifactrep.get(resource.getName(), part); } else { getAndCheck(resource, part); } if (!part.renameTo(dest)) { throw new IOException( "impossible to move part file to definitive one: " + part + " -> " + dest); } } }; }




© 2015 - 2024 Weber Informatics LLC | Privacy Policy