/* * 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.ant; import java.io.File; import java.net.MalformedURLException; import java.text.ParseException; import java.util.ArrayList; import java.util.Arrays; import java.util.Collection; import java.util.Iterator; import java.util.List; import org.apache.ivy.Ivy; import org.apache.ivy.core.LogOptions; import org.apache.ivy.core.module.descriptor.DefaultExcludeRule; import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor; import org.apache.ivy.core.module.descriptor.DependencyDescriptor; import org.apache.ivy.core.module.descriptor.ExtendsDescriptor; import org.apache.ivy.core.module.descriptor.ModuleDescriptor; import org.apache.ivy.core.module.id.ModuleRevisionId; import org.apache.ivy.core.report.ResolveReport; import org.apache.ivy.core.resolve.ResolveOptions; import org.apache.ivy.core.resolve.ResolveProcessException; import org.apache.ivy.core.settings.IvySettings; import org.apache.ivy.util.Message; import org.apache.ivy.util.filter.FilterHelper; import org.apache.tools.ant.BuildException; import org.apache.tools.ant.Project; /** * This task allow to call the Ivy dependency resolution from ant. */ public class IvyResolve extends IvyTask { private File file = null; private String conf = null; private String organisation = null; private String module = null; private String branch = null; private String revision = null; private String pubdate = null; private boolean inline = false; private boolean haltOnFailure = true; private boolean showProgress = true; private boolean useCacheOnly = false; private String type = null; private boolean transitive = true; private boolean refresh = false; private boolean changing = false; private Boolean keep = null; private String failureProperty = null; private boolean useOrigin = false; private String resolveMode = null; private String resolveId = null; private String log = ResolveOptions.LOG_DEFAULT; private boolean checkIfChanged = true; // for backward compatibility private List/* */dependencies = new ArrayList(); private List/* */excludes = new ArrayList(); private List/* */conflicts = new ArrayList(); public boolean isUseOrigin() { return useOrigin; } public void setUseOrigin(boolean useOrigin) { this.useOrigin = useOrigin; } public String getDate() { return pubdate; } public void setDate(String pubdate) { this.pubdate = pubdate; } public String getRevision() { return revision; } public void setRevision(String revision) { this.revision = revision; } public String getBranch() { return branch; } public void setBranch(String branch) { this.branch = branch; } public void setCache(File cache) { cacheAttributeNotSupported(); } public String getConf() { return conf; } public void setConf(String conf) { this.conf = conf; } public File getFile() { return file; } public void setFile(File file) { this.file = file; } public boolean isHaltonfailure() { return haltOnFailure; } public void setHaltonfailure(boolean haltOnFailure) { this.haltOnFailure = haltOnFailure; } public void setShowprogress(boolean show) { this.showProgress = show; } public boolean isUseCacheOnly() { return useCacheOnly; } public void setUseCacheOnly(boolean useCacheOnly) { this.useCacheOnly = useCacheOnly; } public String getType() { return type; } public void setType(String type) { this.type = type; } public boolean isRefresh() { return refresh; } public void setRefresh(boolean refresh) { this.refresh = refresh; } public String getLog() { return log; } public void setLog(String log) { this.log = log; } /** * @deprecated Use {@link #setFailureProperty(String)} instead */ @Deprecated public void setFailurePropery(String failureProperty) { log("The 'failurepropery' attribute is deprecated. " + "Please use the 'failureproperty' attribute instead", Project.MSG_WARN); setFailureProperty(failureProperty); } public void setFailureProperty(String failureProperty) { this.failureProperty = failureProperty; } public String getFailureProperty() { return failureProperty; } public IvyDependency createDependency() { IvyDependency dep = new IvyDependency(); dependencies.add(dep); return dep; } public IvyExclude createExclude() { IvyExclude ex = new IvyExclude(); excludes.add(ex); return ex; } public IvyConflict createConflict() { IvyConflict c = new IvyConflict(); conflicts.add(c); return c; } protected void prepareTask() { super.prepareTask(); Message.setShowProgress(showProgress); } public void doExecute() throws BuildException { Ivy ivy = getIvyInstance(); IvySettings settings = ivy.getSettings(); try { conf = getProperty(conf, settings, "ivy.configurations"); type = getProperty(type, settings, "ivy.resolve.default.type.filter"); String[] confs = splitConfs(conf); boolean childs = !dependencies.isEmpty() || !excludes.isEmpty() || !conflicts.isEmpty(); ResolveReport report; if (childs) { if (isInline()) { throw new BuildException("the inline mode is incompatible with child elements"); } if (organisation != null) { throw new BuildException("'organisation' is not allowed with child elements"); } if (module != null) { throw new BuildException("'module' is not allowed with child elements"); } if (file != null) { throw new BuildException("'file' not allowed with child elements"); } if (!getAllowedLogOptions().contains(log)) { throw new BuildException("invalid option for 'log': " + log + ". Available options are " + getAllowedLogOptions()); } ModuleRevisionId mrid = ModuleRevisionId.newInstance("", "", Ivy.getWorkingRevision()); DefaultModuleDescriptor md = DefaultModuleDescriptor.newBasicInstance(mrid, null); Iterator itDeps = dependencies.iterator(); while (itDeps.hasNext()) { IvyDependency dep = (IvyDependency) itDeps.next(); DependencyDescriptor dd = dep.asDependencyDescriptor(md, "default", settings); md.addDependency(dd); } Iterator itExcludes = excludes.iterator(); while (itExcludes.hasNext()) { IvyExclude exclude = (IvyExclude) itExcludes.next(); DefaultExcludeRule rule = exclude.asRule(settings); rule.addConfiguration("default"); md.addExcludeRule(rule); } Iterator itConflicts = conflicts.iterator(); while (itConflicts.hasNext()) { IvyConflict conflict = (IvyConflict) itConflicts.next(); conflict.addConflict(md, settings); } report = ivy .resolve(md, getResolveOptions(ivy, new String[] {"default"}, settings)); } else if (isInline()) { if (organisation == null) { throw new BuildException("'organisation' is required when using inline mode"); } if (module == null) { throw new BuildException("'module' is required when using inline mode"); } if (file != null) { throw new BuildException("'file' not allowed when using inline mode"); } if (!getAllowedLogOptions().contains(log)) { throw new BuildException("invalid option for 'log': " + log + ". Available options are " + getAllowedLogOptions()); } for (int i = 0; i < confs.length; i++) { if ("*".equals(confs[i])) { confs[i] = "*(public)"; } } if (revision == null) { revision = "latest.integration"; } report = ivy.resolve( ModuleRevisionId.newInstance(organisation, module, branch, revision), getResolveOptions(ivy, confs, settings), changing); } else { if (organisation != null) { throw new BuildException( "'organisation' not allowed when not using 'org' attribute"); } if (module != null) { throw new BuildException("'module' not allowed when not using 'org' attribute"); } if (file == null) { file = getProject().resolveFile(getProperty(settings, "ivy.dep.file")); } report = ivy.resolve(file.toURI().toURL(), getResolveOptions(ivy, confs, settings)); } if (report.hasError()) { if (failureProperty != null) { getProject().setProperty(failureProperty, "true"); } if (isHaltonfailure()) { throw new BuildException("resolve failed - see output for details"); } } setResolved(report, resolveId, isKeep()); confs = report.getConfigurations(); if (isKeep()) { ModuleDescriptor md = report.getModuleDescriptor(); // put resolved infos in ant properties and ivy variables // putting them in ivy variables is important to be able to change from one resolve // call to the other String mdOrg = md.getModuleRevisionId().getOrganisation(); String mdName = md.getModuleRevisionId().getName(); String mdRev = md.getResolvedModuleRevisionId().getRevision(); getProject().setProperty("ivy.organisation", mdOrg); settings.setVariable("ivy.organisation", mdOrg); getProject().setProperty("ivy.module", mdName); settings.setVariable("ivy.module", mdName); getProject().setProperty("ivy.revision", mdRev); settings.setVariable("ivy.revision", mdRev); for (int i = 0; i < md.getInheritedDescriptors().length; i++) { ExtendsDescriptor parent = md.getInheritedDescriptors()[i]; String parentOrg = parent.getResolvedParentRevisionId().getOrganisation(); String parentModule = parent.getResolvedParentRevisionId().getName(); String parentRevision = parent.getResolvedParentRevisionId().getRevision(); String parentBranch = parent.getResolvedParentRevisionId().getBranch(); getProject().setProperty("ivy.parent[" + i + "].organisation", parentOrg); settings.setVariable("ivy.parent[" + i + "].organisation", parentOrg); getProject().setProperty("ivy.parent[" + i + "].module", parentModule); settings.setVariable("ivy.parent[" + i + "].module", parentModule); getProject().setProperty("ivy.parent[" + i + "].revision", parentRevision); settings.setVariable("ivy.parent[" + i + "].revision", parentRevision); if (parentBranch != null) { getProject().setProperty("ivy.parent[" + i + "].branch", parentBranch); settings.setVariable("ivy.parent[" + i + "].branch", parentBranch); } } getProject().setProperty("ivy.parents.count", String.valueOf(md.getInheritedDescriptors().length)); settings.setVariable("ivy.parents.count", String.valueOf(md.getInheritedDescriptors().length)); Boolean hasChanged = null; if (getCheckIfChanged()) { hasChanged = Boolean.valueOf(report.hasChanged()); getProject().setProperty("ivy.deps.changed", hasChanged.toString()); settings.setVariable("ivy.deps.changed", hasChanged.toString()); } getProject().setProperty("ivy.resolved.configurations", mergeConfs(confs)); settings.setVariable("ivy.resolved.configurations", mergeConfs(confs)); if (file != null) { getProject().setProperty("ivy.resolved.file", file.getAbsolutePath()); settings.setVariable("ivy.resolved.file", file.getAbsolutePath()); } if (resolveId != null) { getProject().setProperty("ivy.organisation." + resolveId, mdOrg); settings.setVariable("ivy.organisation." + resolveId, mdOrg); getProject().setProperty("ivy.module." + resolveId, mdName); settings.setVariable("ivy.module." + resolveId, mdName); getProject().setProperty("ivy.revision." + resolveId, mdRev); settings.setVariable("ivy.revision." + resolveId, mdRev); if (getCheckIfChanged()) { // hasChanged has already been set earlier getProject().setProperty("ivy.deps.changed." + resolveId, hasChanged.toString()); settings.setVariable("ivy.deps.changed." + resolveId, hasChanged.toString()); } getProject().setProperty("ivy.resolved.configurations." + resolveId, mergeConfs(confs)); settings.setVariable("ivy.resolved.configurations." + resolveId, mergeConfs(confs)); if (file != null) { getProject().setProperty("ivy.resolved.file." + resolveId, file.getAbsolutePath()); settings.setVariable("ivy.resolved.file." + resolveId, file.getAbsolutePath()); } } } } catch (MalformedURLException e) { throw new BuildException("unable to convert given ivy file to url: " + file + ": " + e, e); } catch (ParseException e) { log(e.getMessage(), Project.MSG_ERR); throw new BuildException("syntax errors in ivy file: " + e, e); } catch (ResolveProcessException e) { throw new BuildException("impossible to resolve dependencies:\n\t" + e.getMessage(), e); } catch (Exception e) { throw new BuildException("impossible to resolve dependencies:\n\t" + e, e); } } protected Collection/* */getAllowedLogOptions() { return Arrays.asList(new String[] {LogOptions.LOG_DEFAULT, LogOptions.LOG_DOWNLOAD_ONLY, LogOptions.LOG_QUIET}); } private ResolveOptions getResolveOptions(Ivy ivy, String[] confs, IvySettings settings) { if (useOrigin) { settings.useDeprecatedUseOrigin(); } return ((ResolveOptions) new ResolveOptions().setLog(log)).setConfs(confs) .setValidate(doValidate(settings)) .setArtifactFilter(FilterHelper.getArtifactTypeFilter(type)).setRevision(revision) .setDate(getPubDate(pubdate, null)).setUseCacheOnly(useCacheOnly) .setRefresh(refresh).setTransitive(transitive).setResolveMode(resolveMode) .setResolveId(resolveId).setCheckIfChanged(checkIfChanged); } public String getModule() { return module; } public void setModule(String module) { this.module = module; } public String getOrganisation() { return organisation; } public void setOrganisation(String organisation) { this.organisation = organisation; } public boolean isTransitive() { return transitive; } public void setTransitive(boolean transitive) { this.transitive = transitive; } public boolean isChanging() { return changing; } public void setChanging(boolean changing) { this.changing = changing; } public boolean isKeep() { return keep == null ? organisation == null : keep.booleanValue(); } public void setKeep(boolean keep) { this.keep = Boolean.valueOf(keep); } public boolean isInline() { return inline; } public void setInline(boolean inline) { this.inline = inline; } public String getResolveId() { return resolveId; } public void setResolveId(String resolveId) { this.resolveId = resolveId; } public String getResolveMode() { return resolveMode; } public void setResolveMode(String resolveMode) { this.resolveMode = resolveMode; } public boolean getCheckIfChanged() { return checkIfChanged; } public void setCheckIfChanged(boolean checkIfChanged) { this.checkIfChanged = checkIfChanged; } }