Index: src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java =================================================================== --- src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java (revision 1538531) +++ src/java/org/apache/ivy/core/cache/DefaultRepositoryCacheManager.java (working copy) @@ -23,11 +23,14 @@ import java.io.InputStream; import java.io.OutputStream; import java.io.UnsupportedEncodingException; +import java.net.MalformedURLException; +import java.net.URL; import java.security.MessageDigest; import java.security.NoSuchAlgorithmException; import java.text.ParseException; import java.util.Date; import java.util.Enumeration; +import java.util.Iterator; import java.util.Map; import java.util.regex.Pattern; import java.util.zip.ZipEntry; @@ -39,6 +42,7 @@ import org.apache.ivy.core.module.descriptor.DefaultArtifact; import org.apache.ivy.core.module.descriptor.DependencyDescriptor; import org.apache.ivy.core.module.descriptor.ModuleDescriptor; +import org.apache.ivy.core.module.id.ArtifactRevisionId; import org.apache.ivy.core.module.id.ModuleRevisionId; import org.apache.ivy.core.module.id.ModuleRules; import org.apache.ivy.core.report.ArtifactDownloadReport; @@ -465,6 +469,7 @@ PropertiesFile cdf = getCachedDataFile(artifact.getModuleRevisionId()); cdf.setProperty(getIsLocalKey(artifact), String.valueOf(origin.isLocal())); cdf.setProperty(getLocationKey(artifact), origin.getLocation()); + cdf.setProperty(getOriginalKey(artifact), getPrefixKey(origin.getArtifact())); if (origin.getLastChecked() != null) { cdf.setProperty(getLastCheckedKey(artifact), origin.getLastChecked().toString()); } @@ -478,9 +483,13 @@ cdf.remove(getLocationKey(artifact)); cdf.remove(getIsLocalKey(artifact)); cdf.remove(getLastCheckedKey(artifact)); + cdf.remove(getOriginalKey(artifact)); cdf.save(); } + private static final Pattern ARTIFACT_KEY_PATTERN = + Pattern.compile(".*:(.*)#(.*)#(.*)#(.*)(\\.location)?"); + public ArtifactOrigin getSavedArtifactOrigin(Artifact artifact) { ModuleRevisionId mrid = artifact.getModuleRevisionId(); if (!lockMetadataArtifact(mrid)) { @@ -493,6 +502,7 @@ String local = cdf.getProperty(getIsLocalKey(artifact)); String lastChecked = cdf.getProperty(getLastCheckedKey(artifact)); String exists = cdf.getProperty(getExistsKey(artifact)); + String original = cdf.getProperty(getOriginalKey(artifact)); boolean isLocal = Boolean.valueOf(local).booleanValue(); @@ -501,6 +511,72 @@ return ArtifactOrigin.unkwnown(artifact); } + if (original != null) { + // original artifact key artifact:[name]#[type]#[ext]#[hashcode] + java.util.regex.Matcher m = ARTIFACT_KEY_PATTERN.matcher(original); + if (m.matches()) { + String origName = m.group(1); + String origType = m.group(2); + String origExt = m.group(3); + + ArtifactRevisionId originArtifactId = ArtifactRevisionId.newInstance( + artifact.getModuleRevisionId(), origName, origType, origExt); + // second check: verify the hashcode of the cached artifact + if (m.group(4).equals("" + originArtifactId.hashCode())) { + try { + artifact = new DefaultArtifact(originArtifactId, + artifact.getPublicationDate(), new URL(location), true); + } catch (MalformedURLException e) { + Message.debug(e); + } + } + } + } else { + // Fallback if cached with old version: + + // if the origin artifact has another extension (e.g. .pom) then make a synthetic + // origin artifact for it + if (!location.endsWith("." + artifact.getExt())) { + // try to find other cached artifact info with same location. This must be the + // origin. We must parse the key as we do not know for sure what the original + // artifact is named. + Iterator it = cdf.entrySet().iterator(); + String ownLocationKey = getLocationKey(artifact); + while (it.hasNext()) { + Map.Entry entry = (Map.Entry) it.next(); + if (entry.getValue().equals(location) + && !ownLocationKey.equals(entry.getKey())) { + // found a match, key is artifact:[name]#[type]#[ext]#[hashcode].location + java.util.regex.Matcher m = ARTIFACT_KEY_PATTERN.matcher( + (String) entry.getKey()); + if (m.matches()) { + String origName = m.group(1); + String origType = m.group(2); + String origExt = m.group(3); + + // first check: the type should end in .original + if (!origType.endsWith(".original")) { + continue; + } + + ArtifactRevisionId originArtifactId = ArtifactRevisionId.newInstance( + artifact.getModuleRevisionId(), origName, origType, origExt); + // second check: verify the hashcode of the cached artifact + if (m.group(4).equals("" + originArtifactId.hashCode())) { + try { + artifact = new DefaultArtifact(originArtifactId, + artifact.getPublicationDate(), new URL(location), true); + } catch (MalformedURLException e) { + Message.debug(e); + } + } + break; + } + } + } + } + } + ArtifactOrigin origin = new ArtifactOrigin(artifact, isLocal, location); if (lastChecked != null) { origin.setLastChecked(Long.valueOf(lastChecked)); @@ -578,6 +654,18 @@ return prefix + ".exists"; } + /** + * Returns the key used to identify the original artifact. + * + * @param artifact + * the artifact to generate the key from. Cannot be null. + * @return the key to be used to reference the original artifact. + */ + private String getOriginalKey(Artifact artifact) { + String prefix = getPrefixKey(artifact); + return prefix + ".original"; + } + private PropertiesFile getCachedDataFile(ModuleDescriptor md) { return getCachedDataFile(md.getResolvedModuleRevisionId()); } @@ -675,6 +763,17 @@ madr.setSize(ivyFile.length()); madr.setArtifactOrigin( getSavedArtifactOrigin(depMD.getMetadataArtifact())); + if (madr.getArtifactOrigin().isExists()) { + if (madr.getArtifactOrigin().isLocal() + && madr.getArtifactOrigin().getArtifact().getUrl() != null) { + madr.setOriginalLocalFile( + new File(madr.getArtifactOrigin().getArtifact().getUrl().toURI())); + } else { + // find locally cached file + madr.setOriginalLocalFile( + getArchiveFileInCache(madr.getArtifactOrigin().getArtifact())); + } + } return new ResolvedModuleRevision( resolver, artResolver, depMD, madr); } else { Index: src/java/org/apache/ivy/core/install/InstallOptions.java =================================================================== --- src/java/org/apache/ivy/core/install/InstallOptions.java (revision 1538473) +++ src/java/org/apache/ivy/core/install/InstallOptions.java (working copy) @@ -25,6 +25,7 @@ private boolean transitive = true; private boolean validate = true; private boolean overwrite = false; + private boolean installOriginalMetadata = false; private String[] confs = {"*"}; private Filter artifactFilter = FilterHelper.NO_FILTER; private String matcherName = PatternMatcher.EXACT; @@ -71,4 +72,11 @@ this.confs = conf; return this; } + public boolean isInstallOriginalMetadata() { + return installOriginalMetadata; + } + public InstallOptions setInstallOriginalMetadata(boolean installOriginalMetadata) { + this.installOriginalMetadata = installOriginalMetadata; + return this; + } } Index: src/java/org/apache/ivy/core/install/InstallEngine.java =================================================================== --- src/java/org/apache/ivy/core/install/InstallEngine.java (revision 1538531) +++ src/java/org/apache/ivy/core/install/InstallEngine.java (working copy) @@ -22,6 +22,7 @@ import java.util.Arrays; import java.util.Date; +import org.apache.ivy.core.cache.ArtifactOrigin; import org.apache.ivy.core.module.descriptor.Configuration; import org.apache.ivy.core.module.descriptor.DefaultDependencyDescriptor; import org.apache.ivy.core.module.descriptor.DefaultModuleDescriptor; @@ -29,6 +30,7 @@ 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.MetadataArtifactDownloadReport; import org.apache.ivy.core.report.ResolveReport; import org.apache.ivy.core.resolve.DownloadOptions; import org.apache.ivy.core.resolve.IvyNode; @@ -153,11 +155,28 @@ } // publish metadata - File localIvyFile = dependencies[i] - .getModuleRevision().getReport().getLocalFile(); + MetadataArtifactDownloadReport artifactDownloadReport = dependencies[i] + .getModuleRevision().getReport(); + File localIvyFile = artifactDownloadReport.getLocalFile(); toResolver.publish( depmd.getMetadataArtifact(), localIvyFile, options.isOverwrite()); + if (options.isInstallOriginalMetadata()) { + if (artifactDownloadReport.getArtifactOrigin() != null + && artifactDownloadReport.getArtifactOrigin().isExists() + && !ArtifactOrigin.isUnknown(artifactDownloadReport.getArtifactOrigin()) + && artifactDownloadReport.getArtifactOrigin().getArtifact() != null + && artifactDownloadReport.getArtifactOrigin().getArtifact() + .getType().endsWith(".original") + && !artifactDownloadReport.getArtifactOrigin().getArtifact() + .getType().equals(depmd.getMetadataArtifact().getType()+".original")) { + // publish original metadata artifact, too, as it has a different type + toResolver.publish(artifactDownloadReport.getArtifactOrigin().getArtifact(), + artifactDownloadReport.getOriginalLocalFile(), + options.isOverwrite()); + } + } + // end module publish toResolver.commitPublishTransaction(); successfullyPublished = true; Index: src/java/org/apache/ivy/ant/IvyInstall.java =================================================================== --- src/java/org/apache/ivy/ant/IvyInstall.java (revision 1538473) +++ src/java/org/apache/ivy/ant/IvyInstall.java (working copy) @@ -57,6 +57,8 @@ private boolean haltOnFailure = true; + private boolean installOriginalMetadata = false; + public void doExecute() throws BuildException { Ivy ivy = getIvyInstance(); IvySettings settings = ivy.getSettings(); @@ -107,7 +109,8 @@ .setOverwrite(overwrite) .setConfs(conf.split(",")) .setArtifactFilter(FilterHelper.getArtifactTypeFilter(type)) - .setMatcherName(matcher)); + .setMatcherName(matcher) + .setInstallOriginalMetadata(installOriginalMetadata)); } catch (Exception e) { throw new BuildException("impossible to install " + mrid + ": " + e, e); } @@ -218,4 +221,11 @@ this.conf = conf; } + public boolean isInstallOriginalMetadata() { + return installOriginalMetadata; + } + + public void setInstallOriginalMetadata(boolean installOriginalMetadata) { + this.installOriginalMetadata = installOriginalMetadata; + } } Index: doc/use/install.html =================================================================== --- doc/use/install.html (revision 1538473) +++ doc/use/install.html (working copy) @@ -66,6 +66,8 @@