package aQute.maven.ns;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import aQute.bnd.maven.support.Pom;
import aQute.maven.MavenRepository.Coordinates;
import aQute.maven.MavenVersionRange;
import aQute.maven.Pom.Dependency;
/**
* 1.0 x >= 1.0 * The default Maven meaning for 1.0 is everything (,) but with
* 1.0 recommended. Obviously this doesn't work for enforcing versions here, so
* it has been redefined as a minimum version. (,1.0] x <= 1.0 (,1.0) x < 1.0
* [1.0] x == 1.0 [1.0,) x >= 1.0 (1.0,) x > 1.0 (1.0,2.0) 1.0 < x < 2.0
* [1.0,2.0] 1.0 <= x <= 2.0 (,1.0],[1.2,) x <= 1.0 or x >= 1.2. Multiple sets
* are comma-separated (,1.1),(1.1,) x != 1.1
*/
public class MavenNamespace {
private static final String DIRECTIVE_FILTER = "filter:";
private static final String DIRECTIVE_EFFECTIVE = "effective:";
private static final String DIRECTIVE_NAME = "name:";
public static final String NAMESPACE = "x-maven";
public static final String GROUPID = "g";
public static final String ARTIFACTID = "a";
public static final String VERSION = "v";
public static final String PACKAGING = "p";
public static final String CLASSIFIER = "c";
final Pom.Scope scope;
final MavenCoordinate name;
final boolean optional;
MavenNamespace(Map<String, Object> ps) {
String name = (String) ps.get(DIRECTIVE_NAME);
if (name == null)
this.name = toCoordinate(ps);
else
this.name = new MavenCoordinate(name);
String scope = (String) ps.get(DIRECTIVE_EFFECTIVE);
if ("provided".equals(scope))
this.scope = Pom.Scope.provided;
else if ("runtime".equals(scope))
this.scope = Pom.Scope.runtime;
else if ("import".equals(scope))
this.scope = Pom.Scope.import_;
else if ("test".equals(scope))
this.scope = Pom.Scope.test;
else if ("system".equals(scope))
this.scope = Pom.Scope.system;
else
this.scope = Pom.Scope.compile;
String resolution = (String) ps.get("resolution:");
optional = (resolution != null && "optional"
.equalsIgnoreCase(resolution));
}
public boolean isTransient() {
return scope == Pom.Scope.compile || scope == Pom.Scope.runtime
|| scope == Pom.Scope.provided;
}
public boolean isOptional() {
return optional;
}
public MavenCoordinate getCoordinate() {
return name;
}
public static Map<String, Object> createRequirement(Dependency dep)
throws Exception {
Map<String, Object> ps = new HashMap<String, Object>();
StringBuilder sb = new StringBuilder("(&(g=");
sb.append(dep.groupId).append(")(a=").append(dep.artifactId)
.append(")");
if (dep.version == null)
dep.version = "0";
MavenVersionRange mr = MavenVersionRange.parse(dep.version);
if (mr != null)
mr.toFilter(sb);
else
sb.append(dep.version);
if (dep.classifier == null) {
sb.append("(!(c=*)");
} else {
sb.append(")(c=").append(dep.classifier);
}
sb.append("))");
MavenCoordinate mc = new MavenCoordinate(dep.groupId, dep.artifactId,
dep.classifier, dep.version);
ps.put(DIRECTIVE_NAME, mc.toString());
ps.put(DIRECTIVE_FILTER, sb.toString());
// TODO do we need another effective time?
ps.put(DIRECTIVE_EFFECTIVE, dep.scope == null ? "maven" : dep.scope);
if (dep.optional)
ps.put("resolution:", "optional");
return ps;
}
static Pattern FILTER_PATTERN = Pattern
.compile("\\((g|a|v|c)=\\s*([-\\w\\d._]+)\\s*\\)");
static Pattern COORDINATE_PATTERN = Pattern
.compile("([-_.\\d\\w]+):([-_.\\d\\w]+)(?:([-_.\\d\\w]+))?@([\\[\\]\\(\\)-_.\\d\\w]+)");
static Pattern COORDINATE_PATTERN_OLD = Pattern
.compile("([-_.\\d\\w]+):([-_.\\d\\w]+)(?::([-_.\\d\\w]+))?(?:(.+))");
public static Coordinates getCoordinatesFromReq(Map<String, Object> ps) {
String filter = (String) ps.get(DIRECTIVE_FILTER);
Coordinates c = new Coordinates();
// String coordinates = (String) ps.get("name:");
// if (coordinates != null) {
// Matcher m2 = COORDINATE_PATTERN.matcher(coordinates);
// if (!m2.matches())
// m2 = COORDINATE_PATTERN_OLD.matcher(coordinates);
//
// if (m2.matches()) {
// c.groupId = m2.group(1);
// c.artifactId = m2.group(2);
// c.classifier = m2.group(3);
// c.version = m2.group(4);
// return c;
// }
// }
//
Matcher m = FILTER_PATTERN.matcher(filter);
while (m.find()) {
String key = m.group(1);
String value = m.group(2);
if (key.equals("a"))
c.artifactId = value;
else if (key.equals("g"))
c.groupId = value;
else if (key.equals("c"))
c.classifier = value;
else if (c.version == null && key.equals("v"))
c.version = value;
else
; // ignore
}
return c;
}
public static MavenCoordinate toCoordinate(Map<String, Object> ps) {
Coordinates cr = getCoordinatesFromReq(ps);
if (cr == null)
return null;
return new MavenCoordinate(cr.groupId, cr.artifactId, cr.classifier,
cr.version);
}
public static MavenNamespace fromRequirement(Map<String, Object> ps) {
return new MavenNamespace(ps);
}
}