Use local copy of latest bndlib code for pre-release testing purposes
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1347815 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/bnd/build/Container.java b/bundleplugin/src/main/java/aQute/bnd/build/Container.java
new file mode 100644
index 0000000..2fb38d9
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/bnd/build/Container.java
@@ -0,0 +1,210 @@
+package aQute.bnd.build;
+
+import java.io.*;
+import java.util.*;
+import java.util.jar.*;
+
+import aQute.bnd.service.RepositoryPlugin.Strategy;
+import aQute.lib.osgi.*;
+
+public class Container {
+ public enum TYPE {
+ REPO, PROJECT, PROJECT_BUNDLE, EXTERNAL, LIBRARY, ERROR
+ }
+
+ final File file;
+ final TYPE type;
+ final String bsn;
+ final String version;
+ final String error;
+ final Project project;
+ volatile Map<String, String> attributes;
+ private long manifestTime;
+ private Manifest manifest;
+
+ Container(Project project, String bsn, String version, TYPE type, File source, String error,
+ Map<String, String> attributes) {
+ this.bsn = bsn;
+ this.version = version;
+ this.type = type;
+ this.file = source != null ? source : new File("/" + bsn + ":" + version + ":" + type);
+ this.project = project;
+ this.error = error;
+ if (attributes == null || attributes.isEmpty())
+ this.attributes = Collections.emptyMap();
+ else
+ this.attributes = attributes;
+ }
+
+ public Container(Project project, File file) {
+ this(project, file.getName(), "project", TYPE.PROJECT, file, null, null);
+ }
+
+ public Container(File file) {
+ this(null, file.getName(), "project", TYPE.EXTERNAL, file, null, null);
+ }
+
+ public File getFile() {
+ return file;
+ }
+
+ /**
+ * Iterate over the containers and get the files they represent
+ *
+ * @param files
+ * @return
+ * @throws Exception
+ */
+ public boolean contributeFiles(List<File> files, Processor reporter) throws Exception {
+ switch (type) {
+ case EXTERNAL:
+ case REPO:
+ files.add(file);
+ return true;
+
+ case PROJECT:
+ File[] fs = project.build();
+ reporter.getInfo(project);
+ if (fs == null)
+ return false;
+
+ for (File f : fs)
+ files.add(f);
+ return true;
+
+ case LIBRARY:
+ List<Container> containers = getMembers();
+ for (Container container : containers) {
+ if (!container.contributeFiles(files, reporter))
+ return false;
+ }
+ return true;
+
+ case ERROR:
+ reporter.error(error);
+ return false;
+ }
+ return false;
+ }
+
+ public String getBundleSymbolicName() {
+ return bsn;
+ }
+
+ public String getVersion() {
+ return version;
+ }
+
+ public TYPE getType() {
+ return type;
+ }
+
+ public String getError() {
+ return error;
+ }
+
+ public boolean equals(Object other) {
+ if (other instanceof Container)
+ return file.equals(((Container) other).file);
+ else
+ return false;
+ }
+
+ public int hashCode() {
+ return file.hashCode();
+ }
+
+ public Project getProject() {
+ return project;
+ }
+
+ /**
+ * Must show the file name or the error formatted as a file name
+ *
+ * @return
+ */
+ public String toString() {
+ if (getError() != null)
+ return "/error/" + getError();
+ else
+ return getFile().getAbsolutePath();
+ }
+
+ public Map<String, String> getAttributes() {
+ return attributes;
+ }
+
+ public void putAttribute(String name, String value) {
+ if (attributes == Collections.<String,String>emptyMap())
+ attributes = new HashMap<String, String>(1);
+ attributes.put(name, value);
+ }
+
+ /**
+ * Return the this if this is anything else but a library. If it is a
+ * library, return the members. This could work recursively, e.g., libraries
+ * can point to libraries.
+ *
+ * @return
+ * @throws Exception
+ */
+ public List<Container> getMembers() throws Exception {
+ List<Container> result = project.newList();
+
+ // Are ww a library? If no, we are the result
+ if (getType() == TYPE.LIBRARY) {
+ // We are a library, parse the file. This is
+ // basically a specification clause per line.
+ // I.e. you can do bsn; version, bsn2; version. But also
+ // spread it out over lines.
+ InputStream in = null;
+ BufferedReader rd = null;
+ String line;
+ try {
+ in = new FileInputStream(file);
+ rd = new BufferedReader(new InputStreamReader(in,
+ Constants.DEFAULT_CHARSET));
+ while ((line = rd.readLine()) != null) {
+ line = line.trim();
+ if (!line.startsWith("#") && line.length() > 0) {
+ List<Container> list = project.getBundles(Strategy.HIGHEST, line, null);
+ result.addAll(list);
+ }
+ }
+ } finally {
+ if (rd != null) {
+ rd.close();
+ }
+ if (in != null) {
+ in.close();
+ }
+ }
+ } else
+ result.add(this);
+
+ return result;
+ }
+
+ /**
+ * Answer the manifest for this container (if possible). Manifest is cached
+ * until the file is renewed.
+ */
+
+ public Manifest getManifest() throws Exception {
+ if (getError() != null || getFile() == null)
+ return null;
+
+ if (manifestTime < getFile().lastModified()) {
+ InputStream in = new FileInputStream(getFile());
+ try {
+ JarInputStream jin = new JarInputStream(in);
+ manifest = jin.getManifest();
+ jin.close();
+ manifestTime = getFile().lastModified();
+ } finally {
+ in.close();
+ }
+ }
+ return manifest;
+ }
+}