Sync bndlib code
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1381708 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Project.java b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
index 9c5c2ec..b6377c6 100644
--- a/bundleplugin/src/main/java/aQute/bnd/build/Project.java
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Project.java
@@ -7,6 +7,7 @@
import java.util.Map.Entry;
import java.util.concurrent.locks.*;
import java.util.jar.*;
+import java.util.regex.*;
import aQute.bnd.header.*;
import aQute.bnd.help.*;
@@ -15,7 +16,6 @@
import aQute.bnd.osgi.eclipse.*;
import aQute.bnd.service.*;
import aQute.bnd.service.RepositoryPlugin.PutResult;
-import aQute.bnd.service.RepositoryPlugin.Strategy;
import aQute.bnd.service.action.*;
import aQute.bnd.version.*;
import aQute.lib.io.*;
@@ -29,6 +29,7 @@
public class Project extends Processor {
+ final static Pattern VERSION_ANNOTATION = Pattern.compile("@\\s*(:?aQute\\.bnd\\.annotation\\.)?Version\\s*\\(\\s*(:?value\\s*=\\s*)?\"(\\d+(:?\\.\\d+(:?\\.\\d+(:?\\.[\\d\\w-_]+)?)?)?)\"\\s*\\)");
final static String DEFAULT_ACTIONS = "build; label='Build', test; label='Test', run; label='Run', clean; label='Clean', release; label='Release', refreshAll; label=Refresh, deploy;label=Deploy";
public final static String BNDFILE = "bnd.bnd";
public final static String BNDCNF = "cnf";
@@ -56,7 +57,7 @@
boolean delayRunDependencies = false;
final ProjectMessages msgs = ReporterMessages.base(this, ProjectMessages.class);
- public Project(Workspace workspace, @SuppressWarnings("unused") File projectDir, File buildFile) throws Exception {
+ public Project(Workspace workspace, File projectDir, File buildFile) throws Exception {
super(workspace);
this.workspace = workspace;
setFileMustExist(false);
@@ -227,26 +228,27 @@
// We might have some other projects we want build
// before we do anything, but these projects are not in
// our path. The -dependson allows you to build them before.
+ // The values are possibly negated globbing patterns.
- List<Project> dependencies = new ArrayList<Project>();
// dependencies.add( getWorkspace().getProject("cnf"));
String dp = getProperty(Constants.DEPENDSON);
- Set<String> requiredProjectNames = new Parameters(dp).keySet();
+ Set<String> requiredProjectNames = new LinkedHashSet<String>(new Parameters(dp).keySet());
+
+ //Allow DependencyConstributors to modify requiredProjectNames
List<DependencyContributor> dcs = getPlugins(DependencyContributor.class);
for (DependencyContributor dc : dcs)
dc.addDependencies(this, requiredProjectNames);
-
- for (String p : requiredProjectNames) {
- Project required = getWorkspace().getProject(p);
- if (required == null)
- msgs.MissingDependson_(p);
- else {
- dependencies.add(required);
- }
-
- }
-
+
+ Instructions is = new Instructions(requiredProjectNames);
+
+ Set<Instruction> unused = new HashSet<Instruction>();
+ Collection<Project> projects = getWorkspace().getAllProjects();
+ Collection<Project> dependencies = is.select(projects, unused, false);
+
+ for (Instruction u: unused)
+ msgs.MissingDependson_(u.getInput());
+
// We have two paths that consists of repo files, projects,
// or some other stuff. The doPath routine adds them to the
// path and extracts the projects so we can build them
@@ -367,7 +369,6 @@
private List<Container> parseBuildpath() throws Exception {
List<Container> bundles = getBundles(Strategy.LOWEST, getProperty(Constants.BUILDPATH), Constants.BUILDPATH);
- appendPackages(Strategy.LOWEST, getProperty(Constants.BUILDPACKAGES), bundles, ResolverMode.build);
return bundles;
}
@@ -422,7 +423,7 @@
Project project = getWorkspace().getProject(bsn);
if (project != null && project.exists()) {
File f = project.getOutput();
- found = new Container(project, bsn, versionRange, Container.TYPE.PROJECT, f, null, attrs);
+ found = new Container(project, bsn, versionRange, Container.TYPE.PROJECT, f, null, attrs, null);
} else {
msgs.NoSuchProject(bsn, spec);
continue;
@@ -433,9 +434,9 @@
if (!f.exists())
error = "File does not exist: " + f.getAbsolutePath();
if (f.getName().endsWith(".lib")) {
- found = new Container(this, bsn, "file", Container.TYPE.LIBRARY, f, error, attrs);
+ found = new Container(this, bsn, "file", Container.TYPE.LIBRARY, f, error, attrs, null);
} else {
- found = new Container(this, bsn, "file", Container.TYPE.EXTERNAL, f, error, attrs);
+ found = new Container(this, bsn, "file", Container.TYPE.EXTERNAL, f, error, attrs, null);
}
} else {
found = getBundle(bsn, versionRange, strategyx, attrs);
@@ -453,7 +454,7 @@
} else {
// Oops, not a bundle in sight :-(
Container x = new Container(this, bsn, versionRange, Container.TYPE.ERROR, null, bsn + ";version="
- + versionRange + " not found", attrs);
+ + versionRange + " not found", attrs, null);
result.add(x);
warning("Can not find URL for bsn " + bsn);
}
@@ -480,72 +481,6 @@
return getBundles(strategy, spec, null);
}
- /**
- * Calculates the containers required to fulfil the {@code -buildpackages}
- * instruction, and appends them to the existing list of containers.
- *
- * @param strategyx
- * The package-version disambiguation strategy.
- * @param spec
- * The value of the @{code -buildpackages} instruction.
- * @throws Exception
- */
- public void appendPackages(Strategy strategyx, String spec, List<Container> resolvedBundles, ResolverMode mode)
- throws Exception {
- Map<File,Container> pkgResolvedBundles = new HashMap<File,Container>();
-
- List<Entry<String,Attrs>> queue = new LinkedList<Map.Entry<String,Attrs>>();
- queue.addAll(new Parameters(spec).entrySet());
-
- while (!queue.isEmpty()) {
- Entry<String,Attrs> entry = queue.remove(0);
-
- String pkgName = entry.getKey();
- Map<String,String> attrs = entry.getValue();
-
- Container found = null;
-
- String versionRange = attrs.get(Constants.VERSION_ATTRIBUTE);
- if ("latest".equals(versionRange) || "snapshot".equals(versionRange))
- found = getPackage(pkgName, versionRange, strategyx, attrs, mode);
-
- if (found == null)
- found = getPackage(pkgName, versionRange, strategyx, attrs, mode);
-
- if (found != null) {
- if (resolvedBundles.contains(found)) {
- // Don't add his bundle because it was already included
- // using -buildpath
- } else {
- List<Container> libs = found.getMembers();
- for (Container cc : libs) {
- Container existing = pkgResolvedBundles.get(cc.file);
- if (existing != null)
- addToPackageList(existing, attrs.get("packages"));
- else {
- addToPackageList(cc, attrs.get("packages"));
- pkgResolvedBundles.put(cc.file, cc);
- }
-
- String importUses = cc.getAttributes().get("import-uses");
- if (importUses != null)
- queue.addAll(0, new Parameters(importUses).entrySet());
- }
- }
- } else {
- // Unable to resolve
- Container x = new Container(this, "X", versionRange, Container.TYPE.ERROR, null, "package " + pkgName
- + ";version=" + versionRange + " not found", attrs);
- resolvedBundles.add(x);
- warning("Can not find URL for package " + pkgName);
- }
- }
-
- for (Container container : pkgResolvedBundles.values()) {
- resolvedBundles.add(container);
- }
- }
-
static void mergeNames(String names, Set<String> set) {
StringTokenizer tokenizer = new StringTokenizer(names, ",");
while (tokenizer.hasMoreTokens())
@@ -577,68 +512,6 @@
}
/**
- * Find a container to fulfil a package requirement
- *
- * @param packageName
- * The package required
- * @param range
- * The package version range required
- * @param strategyx
- * The package-version disambiguation strategy
- * @param attrs
- * Other attributes specified by the search.
- * @return
- * @throws Exception
- */
- public Container getPackage(String packageName, String range, Strategy strategyx, Map<String,String> attrs,
- ResolverMode mode) throws Exception {
- if ("snapshot".equals(range))
- return new Container(this, "", range, Container.TYPE.ERROR, null,
- "snapshot not supported for package lookups", null);
-
- if (attrs == null)
- attrs = new HashMap<String,String>(2);
- attrs.put("package", packageName);
- attrs.put("mode", mode.name());
-
- Strategy useStrategy = findStrategy(attrs, strategyx, range);
-
- List<RepositoryPlugin> plugins = getPlugins(RepositoryPlugin.class);
- for (RepositoryPlugin plugin : plugins) {
- try {
- File result = plugin.get(null, range, useStrategy, attrs);
- if (result != null) {
- if (result.getName().endsWith("lib"))
- return new Container(this, result.getName(), range, Container.TYPE.LIBRARY, result, null, attrs);
- return new Container(this, result.getName(), range, Container.TYPE.REPO, result, null, attrs);
- }
- }
- catch (Exception e) {
- // Ignore... lots of repos will fail here
- }
- }
-
- return new Container(this, "X", range, Container.TYPE.ERROR, null, "package " + packageName + ";version="
- + range + " Not found in " + plugins, null);
- }
-
- private Strategy findStrategy(Map<String,String> attrs, Strategy defaultStrategy, String versionRange) {
- Strategy useStrategy = defaultStrategy;
- String overrideStrategy = attrs.get("strategy");
- if (overrideStrategy != null) {
- if ("highest".equalsIgnoreCase(overrideStrategy))
- useStrategy = Strategy.HIGHEST;
- else if ("lowest".equalsIgnoreCase(overrideStrategy))
- useStrategy = Strategy.LOWEST;
- else if ("exact".equalsIgnoreCase(overrideStrategy))
- useStrategy = Strategy.EXACT;
- }
- if ("latest".equals(versionRange))
- useStrategy = Strategy.HIGHEST;
- return useStrategy;
- }
-
- /**
* The user selected pom in a path. This will place the pom as well as its
* dependencies on the list
*
@@ -663,7 +536,7 @@
Set<Pom> dependencies = pom.getDependencies(act);
for (Pom sub : dependencies) {
File artifact = sub.getArtifact();
- Container container = new Container(artifact);
+ Container container = new Container(artifact, null);
result.add(container);
}
}
@@ -753,10 +626,10 @@
dependson.add(required);
}
for (File f : eclipse.getClasspath()) {
- buildpath.add(new Container(f));
+ buildpath.add(new Container(f, null));
}
for (File f : eclipse.getBootclasspath()) {
- bootclasspath.add(new Container(f));
+ bootclasspath.add(new Container(f, null));
}
sourcepath.addAll(eclipse.getSourcepath());
allsourcepath.addAll(eclipse.getAllSources());
@@ -939,14 +812,18 @@
List<RepositoryPlugin> plugins = workspace.getRepositories();
if (useStrategy == Strategy.EXACT) {
+ if (!Verifier.isVersion(range))
+ return new Container(this, bsn, range, Container.TYPE.ERROR, null, bsn + ";version=" + range
+ + " Invalid version", null, null);
// For an exact range we just iterate over the repos
// and return the first we find.
-
+ Version version = new Version(range);
for (RepositoryPlugin plugin : plugins) {
- File result = plugin.get(bsn, range, Strategy.EXACT, attrs);
+ DownloadBlocker blocker = new DownloadBlocker(this);
+ File result = plugin.get(bsn, version, attrs, blocker);
if (result != null)
- return toContainer(bsn, range, attrs, result);
+ return toContainer(bsn, range, attrs, result, blocker);
}
} else {
VersionRange versionRange = "latest".equals(range) ? new VersionRange("0") : new VersionRange(range);
@@ -959,7 +836,7 @@
SortedMap<Version,RepositoryPlugin> versions = new TreeMap<Version,RepositoryPlugin>();
for (RepositoryPlugin plugin : plugins) {
try {
- List<Version> vs = plugin.versions(bsn);
+ SortedSet<Version> vs = plugin.versions(bsn);
if (vs != null) {
for (Version v : vs) {
if (!versions.containsKey(v) && versionRange.includes(v))
@@ -974,11 +851,13 @@
// Repository
// To query, we must have a real version
if (!versions.isEmpty() && Verifier.isVersion(range)) {
- File file = plugin.get(bsn, range, useStrategy, attrs);
+ Version version = new Version(range);
+ DownloadBlocker blocker = new DownloadBlocker(this);
+ File file = plugin.get(bsn, version, attrs, blocker);
// and the entry must exist
// if it does, return this as a result
if (file != null)
- return toContainer(bsn, range, attrs, file);
+ return toContainer(bsn, range, attrs, file, blocker);
}
}
}
@@ -1004,9 +883,10 @@
if (provider != null) {
RepositoryPlugin repo = versions.get(provider);
String version = provider.toString();
- File result = repo.get(bsn, version, Strategy.EXACT, attrs);
+ DownloadBlocker blocker = new DownloadBlocker(this);
+ File result = repo.get(bsn, provider, attrs, blocker);
if (result != null)
- return toContainer(bsn, version, attrs, result);
+ return toContainer(bsn, version, attrs, result, blocker);
} else
msgs.FoundVersions_ForStrategy_ButNoProvider(versions, useStrategy);
}
@@ -1016,7 +896,7 @@
// If we get this far we ran into an error somewhere
return new Container(this, bsn, range, Container.TYPE.ERROR, null, bsn + ";version=" + range + " Not found in "
- + plugins, null);
+ + plugins, null, null);
}
@@ -1048,15 +928,19 @@
* @param result
* @return
*/
- protected Container toContainer(String bsn, String range, Map<String,String> attrs, File result) {
+ protected Container toContainer(String bsn, String range, Map<String,String> attrs, File result, DownloadBlocker db) {
File f = result;
if (f == null) {
msgs.ConfusedNoContainerFile();
f = new File("was null");
}
+ Container container;
if (f.getName().endsWith("lib"))
- return new Container(this, bsn, range, Container.TYPE.LIBRARY, f, null, attrs);
- return new Container(this, bsn, range, Container.TYPE.REPO, f, null, attrs);
+ container = new Container(this, bsn, range, Container.TYPE.LIBRARY, f, null, attrs, db);
+ else
+ container = new Container(this, bsn, range, Container.TYPE.REPO, f, null, attrs, db);
+
+ return container;
}
/**
@@ -1149,16 +1033,16 @@
}
File[] outputs = getBuildFiles();
for (File output : outputs) {
- for (Deploy d : getPlugins(Deploy.class)) {
- trace("Deploying %s to: %s", output.getName(), d);
- try {
- if (d.deploy(this, output.getName(), new BufferedInputStream(new FileInputStream(output))))
- trace("deployed %s successfully to %s", output, d);
- }
- catch (Exception e) {
- msgs.Deploying(e);
- }
+ for (Deploy d : getPlugins(Deploy.class)) {
+ trace("Deploying %s to: %s", output.getName(), d);
+ try {
+ if (d.deploy(this, output.getName(), new BufferedInputStream(new FileInputStream(output))))
+ trace("deployed %s successfully to %s", output, d);
}
+ catch (Exception e) {
+ msgs.Deploying(e);
+ }
+ }
}
}
@@ -1265,11 +1149,11 @@
* Check if this project needs building. This is defined as:
*/
public boolean isStale() throws Exception {
- if ( workspace.isOffline()) {
+ if (workspace.isOffline()) {
trace("working %s offline, so always stale", this);
return true;
}
-
+
Set<Project> visited = new HashSet<Project>();
return isStale(visited);
}
@@ -1316,7 +1200,7 @@
return true;
}
}
-
+
return false;
}
@@ -1661,7 +1545,8 @@
return jar;
}
- public String _project(@SuppressWarnings("unused") String args[]) {
+ public String _project(@SuppressWarnings("unused")
+ String args[]) {
return getBase().getAbsolutePath();
}
@@ -1722,7 +1607,7 @@
boolean replace(File f, String pattern, String replacement) throws IOException {
final Macro macro = getReplacer();
- Sed sed = new Sed( new Replacer() {
+ Sed sed = new Sed(new Replacer() {
public String process(String line) {
return macro.process(line);
}
@@ -1755,7 +1640,8 @@
/**
* Run all before command plugins
*/
- void before(@SuppressWarnings("unused") Project p, String a) {
+ void before(@SuppressWarnings("unused")
+ Project p, String a) {
List<CommandPlugin> testPlugins = getPlugins(CommandPlugin.class);
for (CommandPlugin testPlugin : testPlugins) {
testPlugin.before(this, a);
@@ -1765,7 +1651,8 @@
/**
* Run all after command plugins
*/
- void after(@SuppressWarnings("unused") Project p, String a, Throwable t) {
+ void after(@SuppressWarnings("unused")
+ Project p, String a, Throwable t) {
List<CommandPlugin> testPlugins = getPlugins(CommandPlugin.class);
for (int i = testPlugins.size() - 1; i >= 0; i--) {
testPlugins.get(i).after(this, a, t);
@@ -1802,7 +1689,8 @@
}
@SuppressWarnings("unchecked")
- public void script(@SuppressWarnings("unused") String type, String script) throws Exception {
+ public void script(@SuppressWarnings("unused")
+ String type, String script) throws Exception {
// TODO check tyiping
List<Scripter> scripters = getPlugins(Scripter.class);
if (scripters.isEmpty()) {
@@ -1814,7 +1702,8 @@
scripters.get(0).eval(x, new StringReader(script));
}
- public String _repos(@SuppressWarnings("unused") String args[]) throws Exception {
+ public String _repos(@SuppressWarnings("unused")
+ String args[]) throws Exception {
List<RepositoryPlugin> repos = getPlugins(RepositoryPlugin.class);
List<String> names = new ArrayList<String>();
for (RepositoryPlugin rp : repos)
@@ -1860,7 +1749,7 @@
for (Builder builder : builders) {
Container c = new Container(this, builder.getBsn(), builder.getVersion(), Container.TYPE.PROJECT,
- getOutputFile(builder.getBsn()), null, null);
+ getOutputFile(builder.getBsn()), null, null, null);
result.add(c);
}
return result;
@@ -1908,7 +1797,8 @@
* @return null or the builder for a sub file.
* @throws Exception
*/
- public Container getDeliverable(String bsn, @SuppressWarnings("unused") Map<String,String> attrs) throws Exception {
+ public Container getDeliverable(String bsn, @SuppressWarnings("unused")
+ Map<String,String> attrs) throws Exception {
Collection< ? extends Builder> builders = getSubBuilders();
for (Builder sub : builders) {
if (sub.getBsn().equals(bsn))
@@ -2021,13 +1911,55 @@
*/
public void setPackageInfo(String packageName, Version version) {
try {
- updatePackageInfoFile(packageName, version);
+ Version current = getPackageInfoJavaVersion(packageName);
+ boolean packageInfoJava = false;
+ if (current != null) {
+ updatePackageInfoJavaFile(packageName, version);
+ packageInfoJava = true;
+ }
+ if (!packageInfoJava || getPackageInfoFile(packageName).exists()) {
+ updatePackageInfoFile(packageName, version);
+ }
}
catch (Exception e) {
msgs.SettingPackageInfoException_(e);
}
}
+ void updatePackageInfoJavaFile(String packageName, final Version newVersion) throws Exception {
+ File file = getPackageInfoJavaFile(packageName);
+
+ if (!file.exists()) {
+ return;
+ }
+
+ // If package/classes are copied into the bundle through Private-Package
+ // etc, there will be no source
+ if (!file.getParentFile().exists()) {
+ return;
+ }
+
+ Version oldVersion = getPackageInfo(packageName);
+
+ if (newVersion.compareTo(oldVersion) == 0) {
+ return;
+ }
+
+ Sed sed = new Sed(new Replacer() {
+ public String process(String line) {
+ Matcher m = VERSION_ANNOTATION.matcher(line);
+ if (m.find()) {
+ return line.substring(0, m.start(3)) + newVersion.toString() + line.substring(m.end(3));
+ }
+ return line;
+ }
+ }, file);
+
+ sed.replace(VERSION_ANNOTATION.pattern(), "$0");
+ sed.setBackup(false);
+ sed.doIt();
+ }
+
void updatePackageInfoFile(String packageName, Version newVersion) throws Exception {
File file = getPackageInfoFile(packageName);
@@ -2038,7 +1970,10 @@
return;
}
- Version oldVersion = getPackageInfo(packageName);
+ Version oldVersion = getPackageInfoVersion(packageName);
+ if (oldVersion == null) {
+ oldVersion = Version.emptyVersion;
+ }
if (newVersion.compareTo(oldVersion) == 0) {
return;
@@ -2055,8 +1990,6 @@
throw new IOException("Could not create directory " + bp);
}
IO.copy(file, binary);
-
- refresh();
}
File getPackageInfoFile(String packageName) {
@@ -2065,10 +1998,31 @@
}
+ File getPackageInfoJavaFile(String packageName) {
+ String path = packageName.replace('.', '/') + "/package-info.java";
+ return IO.getFile(getSrc(), path);
+
+ }
+
public Version getPackageInfo(String packageName) throws IOException {
+
+ Version version = getPackageInfoJavaVersion(packageName);
+ if (version != null) {
+ return version;
+ }
+
+ version = getPackageInfoVersion(packageName);
+ if (version != null) {
+ return version;
+ }
+
+ return Version.emptyVersion;
+ }
+
+ Version getPackageInfoVersion(String packageName) throws IOException {
File packageInfoFile = getPackageInfoFile(packageName);
if (!packageInfoFile.exists()) {
- return Version.emptyVersion;
+ return null;
}
BufferedReader reader = null;
try {
@@ -2086,7 +2040,31 @@
IO.close(reader);
}
}
- return Version.emptyVersion;
+ return null;
+ }
+
+ Version getPackageInfoJavaVersion(String packageName) throws IOException {
+ File packageInfoJavaFile = getPackageInfoJavaFile(packageName);
+ if (!packageInfoJavaFile.exists()) {
+ return null;
+ }
+ BufferedReader reader = null;
+ try {
+ reader = IO.reader(packageInfoJavaFile);
+ String line;
+ while ((line = reader.readLine()) != null) {
+ Matcher matcher = VERSION_ANNOTATION.matcher(line);
+ if (matcher.find()) {
+ return Version.parseVersion(matcher.group(3));
+ }
+ }
+ }
+ finally {
+ if (reader != null) {
+ IO.close(reader);
+ }
+ }
+ return null;
}
/**
@@ -2098,7 +2076,7 @@
if (!f.isFile() && !f.isDirectory()) {
msgs.AddingNonExistentFileToClassPath_(f);
}
- Container container = new Container(f);
+ Container container = new Container(f, null);
classpath.add(container);
}