namespace implementation, still needs testing

git-svn-id: https://svn.apache.org/repos/asf/incubator/ivy/trunk@484141 13f79535-47bb-0310-9956-ffa450edef68
This commit is contained in:
Xavier Hanin 2006-01-23 17:57:29 +00:00
parent ec2825f61b
commit b8e898f4a2
12 changed files with 278 additions and 36 deletions

View File

@ -18,6 +18,8 @@ import java.util.Set;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import fr.jayasoft.ivy.namespace.NamespaceTransformer;
/**
* This class can be used as the default implementation for DependencyDescriptor.
* It implements required methods and enables to fill dependency information
@ -28,6 +30,31 @@ import java.util.regex.Pattern;
*/
public class DefaultDependencyDescriptor implements DependencyDescriptor {
private static final Pattern SELF_FALLBACK_PATTERN = Pattern.compile("@(\\(.*\\))?");
public static DependencyDescriptor transformInstance(DependencyDescriptor dd, NamespaceTransformer t) {
if (t.isIdentity()) {
return dd;
}
ModuleRevisionId transformParentId = t.transform(dd.getParentRevisionId());
ModuleRevisionId transformMrid = t.transform(dd.getDependencyRevisionId());
if (transformParentId.equals(dd.getParentRevisionId()) && transformMrid.equals(dd.getDependencyRevisionId())) {
return dd;
}
DefaultDependencyDescriptor newdd = new DefaultDependencyDescriptor();
newdd._parentId = transformParentId;
newdd._revId = transformMrid;
newdd._force = dd.isForce();
newdd._changing = dd.isChanging();
newdd._transitive = dd.isTransitive();
String[] moduleConfs = dd.getModuleConfigurations();
for (int i = 0; i < moduleConfs.length; i++) {
newdd._confs.put(moduleConfs[i], new ArrayList(Arrays.asList(dd.getDependencyConfigurations(moduleConfs[i]))));
newdd._artifactsExcludes.put(moduleConfs[i], new ArrayList(Arrays.asList(dd.getDependencyArtifactsExcludes(moduleConfs[i]))));
newdd._artifactsIncludes.put(moduleConfs[i], new ArrayList(Arrays.asList(dd.getDependencyArtifactsIncludes(moduleConfs[i]))));
}
return newdd;
}
private ModuleRevisionId _revId;
private Map _confs = new HashMap();
private Map _artifactsIncludes = new HashMap(); // Map (String masterConf -> Collection(DependencyArtifactDescriptor))
@ -79,6 +106,9 @@ public class DefaultDependencyDescriptor implements DependencyDescriptor {
_changing = changing;
}
private DefaultDependencyDescriptor() {
}
public ModuleId getDependencyId() {
return getDependencyRevisionId().getModuleId();
}

View File

@ -6,6 +6,7 @@
package fr.jayasoft.ivy;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Date;
import java.util.HashMap;
@ -15,6 +16,10 @@ import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import fr.jayasoft.ivy.namespace.NameSpaceHelper;
import fr.jayasoft.ivy.namespace.NamespaceTransformer;
import fr.jayasoft.ivy.util.Message;
/**
* @author X.Hanin
*
@ -38,7 +43,43 @@ public class DefaultModuleDescriptor implements ModuleDescriptor {
moduleDescriptor.setLastModified(System.currentTimeMillis());
return moduleDescriptor;
}
public static ModuleDescriptor transformInstance(ModuleDescriptor md, NamespaceTransformer t) {
if (t.isIdentity()) {
return md;
}
DefaultModuleDescriptor nmd = new DefaultModuleDescriptor();
nmd._revId = t.transform(md.getModuleRevisionId());
nmd._resolvedRevId = t.transform(md.getResolvedModuleRevisionId());
nmd._status = md.getStatus();
nmd._publicationDate = md.getPublicationDate();
nmd._resolvedPublicationDate = md.getResolvedPublicationDate();
DependencyDescriptor[] dd = md.getDependencies();
for (int i = 0; i < dd.length; i++) {
nmd._dependencies.add(NameSpaceHelper.transform(dd[i], t));
}
Configuration[] confs = md.getConfigurations();
for (int i = 0; i < confs.length; i++) {
nmd._configurations.put(confs[i].getName(), confs[i]);
Artifact[] arts = md.getArtifacts(confs[i].getName());
for (int j = 0; j < arts.length; j++) {
nmd.addArtifact(confs[i].getName(), NameSpaceHelper.transform(arts[j], t));
}
}
nmd.setDefault(md.isDefault());
if (md instanceof DefaultModuleDescriptor) {
DefaultModuleDescriptor dmd = (DefaultModuleDescriptor)md;
nmd._conflictManagers.putAll(dmd._conflictManagers);
} else {
Message.warn("transformed module descriptor is not a default module descriptor: impossible to copy conflict manager configuration: "+md);
}
nmd._licenses.addAll(Arrays.asList(md.getLicenses()));
nmd._homePage = md.getHomePage();
nmd._lastModified = md.getLastModified();
return nmd;
}
private ModuleRevisionId _revId;
private ModuleRevisionId _resolvedRevId;
private String _status = Status.DEFAULT_STATUS;
@ -275,6 +316,6 @@ public class DefaultModuleDescriptor implements ModuleDescriptor {
public void setLastModified(long lastModified) {
_lastModified = lastModified;
}
}

View File

@ -10,6 +10,14 @@ public class MRIDRule {
private String _org;
private String _module;
private String _rev;
public MRIDRule(String org, String mod, String rev) {
_org = org;
_module = mod;
_rev = rev;
}
public MRIDRule() {
}
public String getModule() {
return _module;
}
@ -29,6 +37,6 @@ public class MRIDRule {
_rev = rev;
}
public String toString() {
return _org+" "+_module+" ";
return "[ "+_org+" "+_module+" "+_rev+" ]";
}
}

View File

@ -17,8 +17,8 @@ import fr.jayasoft.ivy.util.Message;
public class MRIDTransformationRule implements NamespaceTransformer {
private static class MridRuleMatcher {
String[] types = new String[] {"o", "m", "r"};
Matcher[] _matchers = new Matcher[3];
private static final String[] TYPES = new String[] {"o", "m", "r"};
private Matcher[] _matchers = new Matcher[3];
public boolean match(MRIDRule src, ModuleRevisionId mrid) {
_matchers[0] = Pattern.compile(getPattern(src.getOrg())).matcher(mrid.getOrganisation());
@ -37,34 +37,36 @@ public class MRIDTransformationRule implements NamespaceTransformer {
return true;
}
public ModuleRevisionId apply(MRIDRule dest, ModuleRevisionId mrid) {
String org = applyRules(dest.getOrg());
String mod = applyRules(dest.getModule());
String rev = applyRules(dest.getRev());
String org = applyRules(dest.getOrg(), "o");
String mod = applyRules(dest.getModule(), "m");
String rev = applyRules(dest.getRev(), "r");
return ModuleRevisionId.newInstance(org, mod, rev);
}
private String applyRules(String str) {
for (int i = 0; i < types.length; i++) {
str = applyTypeRule(str, types[i], _matchers[i]);
private String applyRules(String str, String type) {
for (int i = 0; i < TYPES.length; i++) {
str = applyTypeRule(str, TYPES[i], type, _matchers[i]);
}
return str;
}
private String applyTypeRule(String rule, String type, Matcher m) {
String res = rule == null ? "$"+type+"0" : rule;
for (int i = 0; i < types.length; i++) {
if (types[i].equals(type)) {
private String applyTypeRule(String rule, String type, String ruleType, Matcher m) {
String res = rule == null ? "$"+ruleType+"0" : rule;
for (int i = 0; i < TYPES.length; i++) {
if (TYPES[i].equals(type)) {
res = res.replaceAll("[^\\\\]\\$"+type, "\\$");
res = res.replaceAll("^\\$"+type, "\\$");
} else {
res = res.replaceAll("[^\\\\]\\$"+types[i], "\\\\\\$"+types[i]);
res = res.replaceAll("^\\$"+types[i], "\\\\\\$"+types[i]);
res = res.replaceAll("[^\\\\]\\$"+TYPES[i], "\\\\\\$"+TYPES[i]);
res = res.replaceAll("^\\$"+TYPES[i], "\\\\\\$"+TYPES[i]);
}
}
StringBuffer sb = new StringBuffer();
m.reset();
m.find();
m.appendReplacement(sb, res);
return sb.toString();
return sb.toString();
}
private String getPattern(String p) {
@ -98,4 +100,8 @@ public class MRIDTransformationRule implements NamespaceTransformer {
return mrid;
}
public boolean isIdentity() {
return false;
}
}

View File

@ -0,0 +1,50 @@
/*
* This file is subject to the licence found in LICENCE.TXT in the root directory of the project.
* Copyright Jayasoft 2005 - All rights reserved
*
* #SNAPSHOT#
*/
package fr.jayasoft.ivy.namespace;
import fr.jayasoft.ivy.Artifact;
import fr.jayasoft.ivy.DefaultArtifact;
import fr.jayasoft.ivy.DefaultDependencyDescriptor;
import fr.jayasoft.ivy.DefaultModuleDescriptor;
import fr.jayasoft.ivy.DefaultModuleRevision;
import fr.jayasoft.ivy.DependencyDescriptor;
import fr.jayasoft.ivy.ModuleDescriptor;
import fr.jayasoft.ivy.ModuleRevisionId;
import fr.jayasoft.ivy.ResolvedModuleRevision;
public class NameSpaceHelper {
public static DependencyDescriptor transform(DependencyDescriptor dd, NamespaceTransformer t) {
return DefaultDependencyDescriptor.transformInstance(dd, t);
}
public static ModuleDescriptor transform(ModuleDescriptor md, NamespaceTransformer t) {
return DefaultModuleDescriptor.transformInstance(md, t);
}
public static ResolvedModuleRevision transform(ResolvedModuleRevision rmr, NamespaceTransformer t) {
if (t.isIdentity()) {
return rmr;
}
ModuleDescriptor md = transform(rmr.getDescriptor(), t);
if (md.equals(rmr.getDescriptor())) {
return rmr;
}
return new DefaultModuleRevision(rmr.getResolver(), md, rmr.isSearched(), rmr.isDownloaded());
}
public static Artifact transform(Artifact artifact, NamespaceTransformer t) {
if (t.isIdentity()) {
return artifact;
}
ModuleRevisionId mrid = t.transform(artifact.getModuleRevisionId());
if (artifact.getModuleRevisionId().equals(mrid)) {
return artifact;
}
return new DefaultArtifact(mrid, artifact.getPublicationDate(), artifact.getName(), artifact.getType(), artifact.getExt());
}
}

View File

@ -28,6 +28,9 @@ public class Namespace {
}
return mrid;
}
public boolean isIdentity() {
return _rules.isEmpty();
}
};
private NamespaceTransformer _toSystemTransformer = new NamespaceTransformer() {
public ModuleRevisionId transform(ModuleRevisionId mrid) {
@ -37,6 +40,9 @@ public class Namespace {
}
return mrid;
}
public boolean isIdentity() {
return _rules.isEmpty();
}
};
public void addRule(NamespaceRule rule) {

View File

@ -10,4 +10,6 @@ import fr.jayasoft.ivy.ModuleRevisionId;
public interface NamespaceTransformer {
public ModuleRevisionId transform(ModuleRevisionId mrid);
public boolean isIdentity();
}

View File

@ -6,11 +6,17 @@
package fr.jayasoft.ivy.resolver;
import fr.jayasoft.ivy.Artifact;
import fr.jayasoft.ivy.DependencyDescriptor;
import fr.jayasoft.ivy.DependencyResolver;
import fr.jayasoft.ivy.Ivy;
import fr.jayasoft.ivy.IvyAware;
import fr.jayasoft.ivy.IvyNode;
import fr.jayasoft.ivy.LatestStrategy;
import fr.jayasoft.ivy.ModuleDescriptor;
import fr.jayasoft.ivy.ModuleRevisionId;
import fr.jayasoft.ivy.ResolveData;
import fr.jayasoft.ivy.ResolvedModuleRevision;
import fr.jayasoft.ivy.namespace.NameSpaceHelper;
import fr.jayasoft.ivy.namespace.Namespace;
import fr.jayasoft.ivy.report.ArtifactDownloadReport;
import fr.jayasoft.ivy.report.DownloadReport;
@ -176,4 +182,39 @@ public abstract class AbstractResolver implements DependencyResolver, IvyAware,
_namespaceName = namespaceName;
}
// Namespace conversion methods
protected ModuleDescriptor toSystem(ModuleDescriptor md) {
return NameSpaceHelper.transform(md, getNamespace().getToSystemTransformer());
}
protected Artifact fromSystem(Artifact artifact) {
return NameSpaceHelper.transform(artifact, getNamespace().getFromSystemTransformer());
}
protected Artifact toSystem(Artifact artifact) {
return NameSpaceHelper.transform(artifact, getNamespace().getToSystemTransformer());
}
protected ResolvedModuleRevision toSystem(ResolvedModuleRevision rmr) {
return NameSpaceHelper.transform(rmr, getNamespace().getToSystemTransformer());
}
protected ModuleRevisionId toSystem(ModuleRevisionId resolvedMrid) {
return getNamespace().getToSystemTransformer().transform(resolvedMrid);
}
protected DependencyDescriptor fromSystem(DependencyDescriptor dd) {
return NameSpaceHelper.transform(dd, getNamespace().getFromSystemTransformer());
}
protected IvyNode getSystemNode(ResolveData data, ModuleRevisionId resolvedMrid) {
return data.getNode(toSystem(resolvedMrid));
}
protected ResolvedModuleRevision findModuleInCache(ResolveData data, ModuleRevisionId mrid) {
return data.getIvy().findModuleInCache(toSystem(mrid), data.getCache(), doValidate(data));
}
}

View File

@ -109,6 +109,8 @@ public abstract class BasicResolver extends AbstractResolver {
}
public ResolvedModuleRevision getDependency(DependencyDescriptor dd, ResolveData data) throws ParseException {
dd = fromSystem(dd);
clearIvyAttempts();
boolean downloaded = false;
boolean searched = false;
@ -129,10 +131,10 @@ public abstract class BasicResolver extends AbstractResolver {
// if we do not have to check modified and if the revision is exact and not changing,
// we first search for it in cache
if (mrid.isExactRevision() && !isCheckmodified() && !dd.isChanging()) {
ResolvedModuleRevision rmr = data.getIvy().findModuleInCache(mrid, data.getCache(), doValidate(data));
ResolvedModuleRevision rmr = findModuleInCache(data, mrid);
if (rmr != null) {
Message.verbose("\t"+getName()+": revision in cache: "+mrid);
return rmr;
return toSystem(rmr);
}
}
URL cachedIvyURL = null;
@ -178,26 +180,26 @@ public abstract class BasicResolver extends AbstractResolver {
// first check if this dependency has not yet been resolved
if (!mrid.isExactRevision() && ModuleRevisionId.isExactRevision(ivyRef.getRevision())) {
resolvedMrid = new ModuleRevisionId(mrid.getModuleId(), ivyRef.getRevision());
IvyNode node = data.getNode(resolvedMrid);
IvyNode node = getSystemNode(data, resolvedMrid);
if (node != null && node.getModuleRevision() != null) {
// this revision has already be resolved : return it
Message.verbose("\t"+getName()+": revision already resolved: "+resolvedMrid);
return searchedRmr(node.getModuleRevision());
return toSystem(searchedRmr(node.getModuleRevision()));
}
}
// now let's see if we can find it in cache and if it is up to date
ResolvedModuleRevision rmr = data.getIvy().findModuleInCache(resolvedMrid, data.getCache(), doValidate(data));
ResolvedModuleRevision rmr = findModuleInCache(data, resolvedMrid);
if (rmr != null) {
if (!isCheckmodified() && !dd.isChanging()) {
Message.verbose("\t"+getName()+": revision in cache: "+resolvedMrid);
return searchedRmr(rmr);
return toSystem(searchedRmr(rmr));
}
long repLastModified = ivyRef.getLastModified();
long cacheLastModified = rmr.getDescriptor().getLastModified();
if (!rmr.getDescriptor().isDefault() && repLastModified <= cacheLastModified) {
Message.verbose("\t"+getName()+": revision in cache (not updated): "+resolvedMrid);
return searchedRmr(rmr);
return toSystem(searchedRmr(rmr));
} else {
Message.verbose("\t"+getName()+": revision in cache is not up to date: "+resolvedMrid);
if (dd.isChanging()) {
@ -212,7 +214,7 @@ public abstract class BasicResolver extends AbstractResolver {
try {
// first check if source file is not cache file itself
if (ResourceHelper.equals(ivyRef.getResource(),
data.getIvy().getIvyFileInCache(data.getCache(), resolvedMrid))) {
data.getIvy().getIvyFileInCache(data.getCache(), toSystem(resolvedMrid)))) {
Message.error("invalid configuration for resolver '"+getName()+"': pointing ivy files to ivy cache is forbidden !");
return null;
}
@ -261,7 +263,7 @@ public abstract class BasicResolver extends AbstractResolver {
for (int i = 0; i < confs.length; i++) {
Artifact[] arts = rmr.getDescriptor().getArtifacts(confs[i]);
for (int j = 0; j < arts.length; j++) {
File artFile = data.getIvy().getArchiveFileInCache(data.getCache(), arts[j]);
File artFile = data.getIvy().getArchiveFileInCache(data.getCache(), toSystem(arts[j]));
if (artFile.exists()) {
Message.debug("deleting "+artFile);
artFile.delete();
@ -317,14 +319,15 @@ public abstract class BasicResolver extends AbstractResolver {
md.setResolvedPublicationDate(new Date(pubDate));
}
ModuleDescriptor systemMd = toSystem(md);
try {
File ivyFile = data.getIvy().getIvyFileInCache(data.getCache(), md.getResolvedModuleRevisionId());
File ivyFile = data.getIvy().getIvyFileInCache(data.getCache(), systemMd.getResolvedModuleRevisionId());
if (ivyRef == null) {
// a basic ivy file is written containing default data
XmlModuleDescriptorWriter.write(md, ivyFile);
XmlModuleDescriptorWriter.write(systemMd, ivyFile);
} else {
// copy and update ivy file from source to cache
parser.toIvyFile(cachedIvyURL, ivyRef.getResource(), ivyFile, md);
parser.toIvyFile(cachedIvyURL, ivyRef.getResource(), ivyFile, systemMd);
long repLastModified = ivyRef.getLastModified();
if (repLastModified > 0) {
ivyFile.setLastModified(repLastModified);
@ -334,8 +337,8 @@ public abstract class BasicResolver extends AbstractResolver {
Message.warn("impossible to copy ivy file to cache : "+ivyRef.getResource());
}
data.getIvy().saveResolver(data.getCache(), md, getName());
return new DefaultModuleRevision(this, md, searched, downloaded);
data.getIvy().saveResolver(data.getCache(), systemMd, getName());
return new DefaultModuleRevision(this, systemMd, searched, downloaded);
}
protected void clearIvyAttempts() {
@ -432,7 +435,11 @@ public abstract class BasicResolver extends AbstractResolver {
adr.setDownloadStatus(DownloadStatus.NO);
adr.setSize(archiveFile.length());
} else {
ResolvedResource artifactRef = findArtifactRef(artifacts[i], null);
Artifact artifact = fromSystem(artifacts[i]);
if (!artifact.equals(artifacts[i])) {
Message.verbose("\t"+getName()+"looking for artifact "+artifact+ " (is "+artifacts[i]+" in system namespace)");
}
ResolvedResource artifactRef = findArtifactRef(artifact, null);
if (artifactRef != null) {
if (ResourceHelper.equals(artifactRef.getResource(),
archiveFile)) {
@ -450,11 +457,15 @@ public abstract class BasicResolver extends AbstractResolver {
artifacts[i].getType(),
artifacts[i].getExt()+".part"));
adr.setSize(get(artifactRef.getResource(), tmp));
tmp.renameTo(archiveFile);
Message.info("\t[SUCCESSFUL ] "+artifacts[i]+" ("+(System.currentTimeMillis()-start)+"ms)");
adr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
if (!tmp.renameTo(archiveFile)) {
Message.warn("\t[FAILED ] "+artifacts[i]+" impossible to move temp file to definitive one ("+(System.currentTimeMillis()-start)+"ms)");
adr.setDownloadStatus(DownloadStatus.FAILED);
} else {
Message.info("\t[SUCCESSFUL ] "+artifacts[i]+" ("+(System.currentTimeMillis()-start)+"ms)");
adr.setDownloadStatus(DownloadStatus.SUCCESSFUL);
}
} catch (Exception ex) {
Message.warn("\t[FAILED ] "+artifacts[i]+" ("+(System.currentTimeMillis()-start)+"ms)");
Message.warn("\t[FAILED ] "+artifacts[i]+" : "+ex.getMessage()+" ("+(System.currentTimeMillis()-start)+"ms)");
adr.setDownloadStatus(DownloadStatus.FAILED);
}
} else {

View File

@ -1207,6 +1207,24 @@ public class ResolveTest extends TestCase {
assertTrue(ivy.getArchiveFileInCache(_cache, "fr.jayasoft", "test", "1.0", "test", "jar", "jar").exists());
}
public void testNamespaceMapping() throws Exception {
Ivy ivy = new Ivy();
ivy.configure(new File("test/repositories/namespace/ivyconf.xml"));
ResolveReport report = ivy.resolve(ResolveTest.class.getResource("ivy-namespace.xml"),
null, new String[] {"*"}, _cache, null, true);
assertNotNull(report);
ModuleDescriptor md = report.getModuleDescriptor();
assertNotNull(md);
ModuleRevisionId mrid = ModuleRevisionId.newInstance("jayasoft", "namespace", "1.0");
assertEquals(mrid, md.getModuleRevisionId());
assertTrue(ivy.getResolvedIvyFileInCache(_cache, mrid).exists());
// dependencies
assertTrue(ivy.getIvyFileInCache(_cache, ModuleRevisionId.newInstance("systemorg", "systemmod", "1.0")).exists());
assertTrue(ivy.getArchiveFileInCache(_cache, "systemorg", "systemmod", "1.0", "A", "jar", "jar").exists());
}
////////////////////////////////////////////////////////////
// helper methods to ease the tests
////////////////////////////////////////////////////////////

View File

@ -0,0 +1,7 @@
<ivy-module version="1.0">
<info organisation="jayasoft" module="namespace" revision="1.0" />
<dependencies>
<dependency org="systemorg" name="systemmod" rev="1.0" />
</dependencies>
</ivy-module>

View File

@ -0,0 +1,22 @@
/*
* This file is subject to the licence found in LICENCE.TXT in the root directory of the project.
* Copyright Jayasoft 2005 - All rights reserved
*
* #SNAPSHOT#
*/
package fr.jayasoft.ivy.namespace;
import fr.jayasoft.ivy.ModuleRevisionId;
import junit.framework.TestCase;
public class MRIDTransformationRuleTest extends TestCase {
public void testTransformation() {
MRIDTransformationRule r = new MRIDTransformationRule();
r.addSrc(new MRIDRule("apache", "commons.+", null));
r.addDest(new MRIDRule("$m0", "$m0", null));
assertEquals(ModuleRevisionId.newInstance("commons-client", "commons-client", "1.0"),
r.transform(ModuleRevisionId.newInstance("apache", "commons-client", "1.0")));
}
}