Update to latest Bnd Tool (0.0.310)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@740066 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/pom.xml b/bundleplugin/pom.xml
index 8ce26d3..e7675d0 100644
--- a/bundleplugin/pom.xml
+++ b/bundleplugin/pom.xml
@@ -56,7 +56,7 @@
<dependency>
<groupId>biz.aQute</groupId>
<artifactId>bndlib</artifactId>
- <version>0.0.308</version>
+ <version>0.0.310</version>
</dependency>
<dependency>
<groupId>net.sf.kxml</groupId>
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/About.java b/bundleplugin/src/main/java/aQute/lib/osgi/About.java
deleted file mode 100644
index 52a2529..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/About.java
+++ /dev/null
@@ -1,48 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-/**
- * This package contains a number of classes that assists by analyzing JARs and
- * constructing bundles.
- *
- * The Analyzer class can be used to analyze an existing bundle and can create a
- * manifest specification from proposed (wildcard) Export-Package,
- * Bundle-Includes, and Import-Package headers.
- *
- * The Builder class can use the headers to construct a JAR from the classpath.
- *
- * The Verifier class can take an existing JAR and verify that all headers are
- * correctly set. It will verify the syntax of the headers, match it against the
- * proper contents, and verify imports and exports.
- *
- * A number of utility classes are available.
- *
- * Jar, provides an abstraction of a Jar file. It has constructors for creating
- * a Jar from a stream, a directory, or a jar file. A Jar, keeps a collection
- * Resource's. There are Resource implementations for File, from ZipFile, or from
- * a stream (which copies the data). The Jar tries to minimize the work during
- * build up so that it is cheap to use. The Resource's can be used to iterate
- * over the names and later read the resources when needed.
- *
- * Clazz, provides a parser for the class files. This will be used to define the
- * imports and exports.
- *
- * A key component in this library is the Map. Headers are translated to Maps of Maps. OSGi
- * header syntax is like:
- * <pre>
- * header = clause ( ',' clause ) *
- * clause = file ( ';' file ) * ( parameter ) *
- * param = attr '=' value | directive ':=' value
- * </pre>
- * These headers are translated to a Map that contains all headers (the order is
- * maintained). Each additional file in a header definition will have its own
- * entry (only native code does not work this way). The clause is represented
- * as another map. The ':' of directives is considered part of the name. This
- * allows attributes and directives to be maintained in the clause map.
- *
- * @version $Revision: 1.1 $
- */
-public class About {
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/AbstractResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/AbstractResource.java
deleted file mode 100644
index 532b33e..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/AbstractResource.java
+++ /dev/null
@@ -1,50 +0,0 @@
-package aQute.lib.osgi;
-
-import java.io.*;
-
-public abstract class AbstractResource implements Resource {
- String extra;
- byte[] calculated;
- long lastModified;
-
- protected AbstractResource(long modified) {
- lastModified = modified;
- }
-
- public String getExtra() {
- return extra;
- }
-
- public long lastModified() {
- return lastModified;
- }
-
- public InputStream openInputStream() throws IOException {
- return new ByteArrayInputStream(getLocalBytes());
- }
-
- private byte[] getLocalBytes() throws IOException {
- try {
- if (calculated != null)
- return calculated;
-
- return calculated = getBytes();
- } catch (IOException e) {
- throw e;
- } catch (Exception e) {
- IOException ee = new IOException("Opening resource");
- ee.initCause(e);
- throw ee;
- }
- }
-
- public void setExtra(String extra) {
- this.extra = extra;
- }
-
- public void write(OutputStream out) throws IOException {
- out.write(getLocalBytes());
- }
-
- abstract protected byte[] getBytes() throws Exception;
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java b/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java
deleted file mode 100644
index f3954bd..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Analyzer.java
+++ /dev/null
@@ -1,1885 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-/**
- * This class can calculate the required headers for a (potential) JAR file. It
- * analyzes a directory or JAR for the packages that are contained and that are
- * referred to by the bytecodes. The user can the use regular expressions to
- * define the attributes and directives. The matching is not fully regex for
- * convenience. A * and ? get a . prefixed and dots are escaped.
- *
- * <pre>
- * *;auto=true any
- * org.acme.*;auto=true org.acme.xyz
- * org.[abc]*;auto=true org.acme.xyz
- * </pre>
- *
- * Additional, the package instruction can start with a '=' or a '!'. The '!'
- * indicates negation. Any matching package is removed. The '=' is literal, the
- * expression will be copied verbatim and no matching will take place.
- *
- * Any headers in the given properties are used in the output properties.
- */
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.jar.*;
-import java.util.jar.Attributes.*;
-import java.util.regex.*;
-
-import aQute.bnd.service.*;
-import aQute.lib.filter.*;
-
-public class Analyzer extends Processor {
-
- static Pattern doNotCopy = Pattern
- .compile("CVS|.svn");
- static String version;
- static Pattern versionPattern = Pattern
- .compile("(\\d+\\.\\d+)\\.\\d+.*");
- final Map<String, Map<String, String>> contained = newHashMap(); // package
- final Map<String, Map<String, String>> referred = newHashMap(); // package
- final Map<String, Set<String>> uses = newHashMap(); // package
- Map<String, Clazz> classspace;
- Map<String, Map<String, String>> exports;
- Map<String, Map<String, String>> imports;
- Map<String, Map<String, String>> bundleClasspath; // Bundle
- final Map<String, Map<String, String>> ignored = newHashMap(); // Ignored
- // packages
- Jar dot;
- Map<String, Map<String, String>> classpathExports;
-
- String activator;
-
- final List<Jar> classpath = newList();
-
- static Properties bndInfo;
-
- boolean analyzed;
- String bsn;
-
- public Analyzer(Processor parent) {
- super(parent);
- }
-
- public Analyzer() {
- }
-
- /**
- * Specifically for Maven
- *
- * @param properties
- * the properties
- */
-
- public static Properties getManifest(File dirOrJar) throws IOException {
- Analyzer analyzer = new Analyzer();
- analyzer.setJar(dirOrJar);
- Properties properties = new Properties();
- properties.put(IMPORT_PACKAGE, "*");
- properties.put(EXPORT_PACKAGE, "*");
- analyzer.setProperties(properties);
- Manifest m = analyzer.calcManifest();
- Properties result = new Properties();
- for (Iterator<Object> i = m.getMainAttributes().keySet().iterator(); i
- .hasNext();) {
- Attributes.Name name = (Attributes.Name) i.next();
- result.put(name.toString(), m.getMainAttributes().getValue(name));
- }
- return result;
- }
-
- /**
- * Calcualtes the data structures for generating a manifest.
- *
- * @throws IOException
- */
- public void analyze() throws IOException {
- if (!analyzed) {
- analyzed = true;
- classpathExports = newHashMap();
- activator = getProperty(BUNDLE_ACTIVATOR);
- bundleClasspath = parseHeader(getProperty(BUNDLE_CLASSPATH));
-
- analyzeClasspath();
-
- classspace = analyzeBundleClasspath(dot, bundleClasspath,
- contained, referred, uses);
-
- for (AnalyzerPlugin plugin : getPlugins(AnalyzerPlugin.class)) {
- if (plugin instanceof AnalyzerPlugin) {
- AnalyzerPlugin analyzer = (AnalyzerPlugin) plugin;
- try {
- boolean reanalyze = analyzer.analyzeJar(this);
- if (reanalyze)
- classspace = analyzeBundleClasspath(dot,
- bundleClasspath, contained, referred, uses);
- } catch (Exception e) {
- error("Plugin Analyzer " + analyzer
- + " throws exception " + e);
- e.printStackTrace();
- }
- }
- }
-
- if (activator != null) {
- // Add the package of the activator to the set
- // of referred classes. This must be done before we remove
- // contained set.
- int n = activator.lastIndexOf('.');
- if (n > 0) {
- referred.put(activator.substring(0, n),
- new LinkedHashMap<String, String>());
- }
- }
-
- referred.keySet().removeAll(contained.keySet());
- if (referred.containsKey(".")) {
- error("The default package '.' is not permitted by the Import-Package syntax. \n"
- + " This can be caused by compile errors in Eclipse because Eclipse creates \n"
- + "valid class files regardless of compile errors.\n"
- + "The following package(s) import from the default package "
- + getUsedBy("."));
- }
-
- Map<String, Map<String, String>> exportInstructions = parseHeader(getProperty(EXPORT_PACKAGE));
- Map<String, Map<String, String>> additionalExportInstructions = parseHeader(getProperty(EXPORT_CONTENTS));
- exportInstructions.putAll(additionalExportInstructions);
- Map<String, Map<String, String>> importInstructions = parseHeader(getImportPackages());
- Map<String, Map<String, String>> dynamicImports = parseHeader(getProperty(DYNAMICIMPORT_PACKAGE));
-
- if (dynamicImports != null) {
- // Remove any dynamic imports from the referred set.
- referred.keySet().removeAll(dynamicImports.keySet());
- }
-
- Map<String, Map<String, String>> superfluous = newHashMap();
- // Tricky!
- for (Iterator<String> i = exportInstructions.keySet().iterator(); i
- .hasNext();) {
- String instr = i.next();
- if (!instr.startsWith("!"))
- superfluous.put(instr, exportInstructions.get(instr));
- }
-
- exports = merge("export-package", exportInstructions, contained,
- superfluous.keySet(), null);
-
- // disallow export of default package
- exports.remove(".");
-
- for (Iterator<Map.Entry<String, Map<String, String>>> i = superfluous
- .entrySet().iterator(); i.hasNext();) {
- // It is possible to mention metadata directories in the export
- // explicitly, they are then exported and removed from the
- // warnings. Note that normally metadata directories are not
- // exported.
- Map.Entry<String, Map<String, String>> entry = i.next();
- String pack = entry.getKey();
- if (isDuplicate(pack))
- i.remove();
- else if (isMetaData(pack)) {
- exports.put(pack, entry.getValue());
- i.remove();
- }
- }
-
- if (!superfluous.isEmpty()) {
- warning("Superfluous export-package instructions: "
- + superfluous.keySet());
- }
-
- // Add all exports that do not have an -noimport: directive
- // to the imports.
- Map<String, Map<String, String>> referredAndExported = newMap(referred);
- referredAndExported.putAll(addExportsToImports(exports));
-
- // match the imports to the referred and exported packages,
- // merge the info for matching packages
- Set<String> extra = new TreeSet<String>(importInstructions.keySet());
- imports = merge("import-package", importInstructions,
- referredAndExported, extra, ignored);
-
- // Instructions that have not been used could be superfluous
- // or if they do not contain wildcards, should be added
- // as extra imports, the user knows best.
- for (Iterator<String> i = extra.iterator(); i.hasNext();) {
- String p = i.next();
- if (p.startsWith("!") || p.indexOf('*') >= 0
- || p.indexOf('?') >= 0 || p.indexOf('[') >= 0) {
- if (!isResourceOnly())
- warning("Did not find matching referal for " + p);
- } else {
- Map<String, String> map = importInstructions.get(p);
- imports.put(p, map);
- }
- }
-
- // See what information we can find to augment the
- // imports. I.e. look on the classpath
- augmentImports();
-
- // Add the uses clause to the exports
- doUses(exports, uses, imports);
- }
- }
-
- /**
- * Copy the input collection into an output set but skip names that have
- * been marked as duplicates or are optional.
- *
- * @param superfluous
- * @return
- */
- Set<Instruction> removeMarkedDuplicates(Collection<Instruction> superfluous) {
- Set<Instruction> result = new HashSet<Instruction>();
- for (Iterator<Instruction> i = superfluous.iterator(); i.hasNext();) {
- Instruction instr = (Instruction) i.next();
- if (!isDuplicate(instr.getPattern()) && !instr.isOptional())
- result.add(instr);
- }
- return result;
- }
-
- /**
- * Analyzer has an empty default but the builder has a * as default.
- *
- * @return
- */
- protected String getImportPackages() {
- return getProperty(IMPORT_PACKAGE);
- }
-
- /**
- *
- * @return
- */
- boolean isResourceOnly() {
- return getProperty(RESOURCEONLY, "false").equalsIgnoreCase("true");
- }
-
- /**
- * Answer the list of packages that use the given package.
- */
- Set<String> getUsedBy(String pack) {
- Set<String> set = newSet();
- for (Iterator<Map.Entry<String, Set<String>>> i = uses.entrySet()
- .iterator(); i.hasNext();) {
- Map.Entry<String, Set<String>> entry = i.next();
- Set<String> used = entry.getValue();
- if (used.contains(pack))
- set.add(entry.getKey());
- }
- return set;
- }
-
- /**
- * One of the main workhorses of this class. This will analyze the current
- * setp and calculate a new manifest according to this setup. This method
- * will also set the manifest on the main jar dot
- *
- * @return
- * @throws IOException
- */
- public Manifest calcManifest() throws IOException {
- analyze();
- Manifest manifest = new Manifest();
- Attributes main = manifest.getMainAttributes();
-
- main.put(Attributes.Name.MANIFEST_VERSION, "1.0");
- main.putValue(BUNDLE_MANIFESTVERSION, "2");
-
- boolean noExtraHeaders = "true"
- .equalsIgnoreCase(getProperty(NOEXTRAHEADERS));
-
- if (!noExtraHeaders) {
- main.putValue(CREATED_BY, System.getProperty("java.version") + " ("
- + System.getProperty("java.vendor") + ")");
- main.putValue(TOOL, "Bnd-" + getVersion());
- main.putValue(BND_LASTMODIFIED, "" + System.currentTimeMillis());
- }
- String exportHeader = printClauses(exports,
- "uses:|include:|exclude:|mandatory:|" + IMPORT_DIRECTIVE, true);
-
- if (exportHeader.length() > 0)
- main.putValue(EXPORT_PACKAGE, exportHeader);
- else
- main.remove(EXPORT_PACKAGE);
-
- Map<String, Map<String, String>> temp = removeKeys(imports, "java.");
- if (!temp.isEmpty()) {
- main.putValue(IMPORT_PACKAGE, printClauses(temp, "resolution:"));
- } else {
- main.remove(IMPORT_PACKAGE);
- }
-
- temp = newMap(contained);
- temp.keySet().removeAll(exports.keySet());
-
- if (!temp.isEmpty())
- main.putValue(PRIVATE_PACKAGE, printClauses(temp, ""));
- else
- main.remove(PRIVATE_PACKAGE);
-
- if (!ignored.isEmpty()) {
- main.putValue(IGNORE_PACKAGE, printClauses(ignored, ""));
- } else {
- main.remove(IGNORE_PACKAGE);
- }
-
- if (bundleClasspath != null && !bundleClasspath.isEmpty())
- main.putValue(BUNDLE_CLASSPATH, printClauses(bundleClasspath, ""));
- else
- main.remove(BUNDLE_CLASSPATH);
-
- Map<String, Map<String, String>> l = doServiceComponent(getProperty(SERVICE_COMPONENT));
- if (!l.isEmpty())
- main.putValue(SERVICE_COMPONENT, printClauses(l, ""));
- else
- main.remove(SERVICE_COMPONENT);
-
- for (Enumeration<?> h = getProperties().propertyNames(); h
- .hasMoreElements();) {
- String header = (String) h.nextElement();
- if (header.trim().length() == 0) {
- warning("Empty property set with value: "
- + getProperties().getProperty(header));
- continue;
- }
- if (!Character.isUpperCase(header.charAt(0))) {
- if (header.charAt(0) == '@')
- doNameSection(manifest, header);
- continue;
- }
-
- if (header.equals(BUNDLE_CLASSPATH)
- || header.equals(EXPORT_PACKAGE)
- || header.equals(IMPORT_PACKAGE))
- continue;
-
- if ( header.equalsIgnoreCase("Name")) {
- error("Your bnd file contains a header called 'Name'. This interferes with the manifest name section.");
- continue;
- }
-
- if (Verifier.HEADER_PATTERN.matcher(header).matches()) {
- String value = getProperty(header);
- if (value != null && main.getValue(header) == null) {
- if (value.trim().length() == 0)
- main.remove(header);
- else
- main.putValue(header, value);
- }
- } else {
- // TODO should we report?
- }
- }
-
- //
- // Calculate the bundle symbolic name if it is
- // not set.
- // 1. set
- // 2. name of properties file (must be != bnd.bnd)
- // 3. name of directory, which is usualy project name
- //
- String bsn = getBsn();
- if (main.getValue(BUNDLE_SYMBOLICNAME) == null) {
- main.putValue(BUNDLE_SYMBOLICNAME, bsn);
- }
-
- //
- // Use the same name for the bundle name as BSN when
- // the bundle name is not set
- //
- if (main.getValue(BUNDLE_NAME) == null) {
- main.putValue(BUNDLE_NAME, bsn);
- }
-
- if (main.getValue(BUNDLE_VERSION) == null)
- main.putValue(BUNDLE_VERSION, "0");
-
- // Copy old values into new manifest, when they
- // exist in the old one, but not in the new one
- merge(manifest, dot.getManifest());
-
- // Remove all the headers mentioned in -removeheaders
- Map<String, Map<String, String>> removes = parseHeader(getProperty(REMOVE_HEADERS));
- for (Iterator<String> i = removes.keySet().iterator(); i.hasNext();) {
- String header = i.next();
- for (Iterator<Object> j = main.keySet().iterator(); j.hasNext();) {
- Attributes.Name attr = (Attributes.Name) j.next();
- if (attr.toString().matches(header)) {
- j.remove();
- progress("Removing header: " + header);
- }
- }
- }
-
- dot.setManifest(manifest);
- return manifest;
- }
-
- /**
- * This method is called when the header starts with a @, signifying
- * a name section header. The name part is defined by replacing all the @
- * signs to a /, removing the first and the last, and using the last
- * part as header name:
- * <pre>
- * @org@osgi@service@event@Implementation-Title
- * </pre>
- * This will be the header Implementation-Title in the org/osgi/service/event
- * named section.
- *
- * @param manifest
- * @param header
- */
- private void doNameSection(Manifest manifest, String header) {
- String path = header.replace('@', '/');
- int n = path.lastIndexOf('/');
- // Must succeed because we start with @
- String name = path.substring(n + 1);
- // Skip first /
- path = path.substring(1, n);
- if (name.length() != 0 && path.length() != 0) {
- Attributes attrs = manifest.getAttributes(path);
- if (attrs == null) {
- attrs = new Attributes();
- manifest.getEntries().put(path, attrs);
- }
- attrs.putValue(name, getProperty(header));
- } else {
- warning(
- "Invalid header (starts with @ but does not seem to be for the Name section): %s",
- header);
- }
- }
-
- /**
- * Clear the key part of a header. I.e. remove everything from the first ';'
- *
- * @param value
- * @return
- */
- public String getBsn() {
- String value = getProperty(BUNDLE_SYMBOLICNAME);
- if (value == null) {
- if (getPropertiesFile() != null)
- value = getPropertiesFile().getName();
-
- if (value == null || value.equals("bnd.bnd"))
- value = getBase().getName();
- else if (value.endsWith(".bnd"))
- value = value.substring(0, value.length() - 4);
- }
-
- if (value == null)
- return "untitled";
-
- int n = value.indexOf(';');
- if (n > 0)
- value = value.substring(0, n);
- return value.trim();
- }
-
- /**
- * Calculate an export header solely based on the contents of a JAR file
- *
- * @param bundle
- * The jar file to analyze
- * @return
- */
- public String calculateExportsFromContents(Jar bundle) {
- String ddel = "";
- StringBuffer sb = new StringBuffer();
- Map<String, Map<String, Resource>> map = bundle.getDirectories();
- for (Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
- String directory = (String) i.next();
- if (directory.equals("META-INF")
- || directory.startsWith("META-INF/"))
- continue;
- if (directory.equals("OSGI-OPT")
- || directory.startsWith("OSGI-OPT/"))
- continue;
- if (directory.equals("/"))
- continue;
-
- if (directory.endsWith("/"))
- directory = directory.substring(0, directory.length() - 1);
-
- directory = directory.replace('/', '.');
- sb.append(ddel);
- sb.append(directory);
- ddel = ",";
- }
- return sb.toString();
- }
-
- /**
- * Check if a service component header is actually referring to a class. If
- * so, replace the reference with an XML file reference. This makes it
- * easier to create and use components.
- *
- * @throws UnsupportedEncodingException
- *
- */
- public Map<String, Map<String, String>> doServiceComponent(
- String serviceComponent) throws IOException {
- Map<String, Map<String, String>> list = newMap();
- Map<String, Map<String, String>> sc = parseHeader(serviceComponent);
- if (!sc.isEmpty()) {
- for (Iterator<Map.Entry<String, Map<String, String>>> i = sc
- .entrySet().iterator(); i.hasNext();) {
- Map.Entry<String, Map<String, String>> entry = i.next();
- String name = entry.getKey();
- Map<String, String> info = entry.getValue();
- if (name == null) {
- error("No name in Service-Component header: " + info);
- continue;
- }
- if (dot.exists(name)) {
- // Normal service component
- list.put(name, info);
- } else {
- String impl = name;
- if (info.containsKey(COMPONENT_IMPLEMENTATION))
- impl = info.get(COMPONENT_IMPLEMENTATION);
-
- if (!checkClass(impl))
- error("Not found Service-Component header: " + name);
- else {
- // We have a definition, so make an XML resources
- Resource resource = createComponentResource(name, info);
- dot.putResource("OSGI-INF/" + name + ".xml", resource);
- Map<String, String> empty = Collections.emptyMap();
- list.put("OSGI-INF/" + name + ".xml", empty);
- }
- }
- }
- }
- return list;
- }
-
- public Map<String, Map<String, String>> getBundleClasspath() {
- return bundleClasspath;
- }
-
- public Map<String, Map<String, String>> getContained() {
- return contained;
- }
-
- public Map<String, Map<String, String>> getExports() {
- return exports;
- }
-
- public Map<String, Map<String, String>> getImports() {
- return imports;
- }
-
- public Jar getJar() {
- return dot;
- }
-
- public Map<String, Map<String, String>> getReferred() {
- return referred;
- }
-
- /**
- * Return the set of unreachable code depending on exports and the bundle
- * activator.
- *
- * @return
- */
- public Set<String> getUnreachable() {
- Set<String> unreachable = new HashSet<String>(uses.keySet()); // all
- for (Iterator<String> r = exports.keySet().iterator(); r.hasNext();) {
- String packageName = r.next();
- removeTransitive(packageName, unreachable);
- }
- if (activator != null) {
- String pack = activator.substring(0, activator.lastIndexOf('.'));
- removeTransitive(pack, unreachable);
- }
- return unreachable;
- }
-
- public Map<String, Set<String>> getUses() {
- return uses;
- }
-
- /**
- * Get the version from the manifest, a lot of work!
- *
- * @return version or unknown.
- */
- public String getVersion() {
- return getBndInfo("version", "<unknown version>");
- }
-
- public long getBndLastModified() {
- String time = getBndInfo("modified", "0");
- try {
- return Long.parseLong(time);
- } catch (Exception e) {
- }
- return 0;
- }
-
- public String getBndInfo(String key, String defaultValue) {
- if (bndInfo == null) {
- bndInfo = new Properties();
- try {
- InputStream in = Analyzer.class.getResourceAsStream("bnd.info");
- if (in != null) {
- bndInfo.load(in);
- in.close();
- }
- } catch (IOException ioe) {
- warning("Could not read bnd.info in " + Analyzer.class.getPackage()
- + ioe);
- }
- }
- return bndInfo.getProperty(key, defaultValue);
- }
-
- /**
- * Merge the existing manifest with the instructions.
- *
- * @param manifest
- * The manifest to merge with
- * @throws IOException
- */
- public void mergeManifest(Manifest manifest) throws IOException {
- if (manifest != null) {
- Attributes attributes = manifest.getMainAttributes();
- for (Iterator<Object> i = attributes.keySet().iterator(); i
- .hasNext();) {
- Name name = (Name) i.next();
- String key = name.toString();
- // Dont want instructions
- if (key.startsWith("-"))
- continue;
-
- if (getProperty(key) == null)
- setProperty(key, (String) attributes.get(name));
- }
- }
- }
-
- // public Signer getSigner() {
- // String sign = getProperty("-sign");
- // if (sign == null) return null;
- //
- // Map parsed = parseHeader(sign);
- // Signer signer = new Signer();
- // String password = (String) parsed.get("password");
- // if (password != null) {
- // signer.setPassword(password);
- // }
- //
- // String keystore = (String) parsed.get("keystore");
- // if (keystore != null) {
- // File f = new File(keystore);
- // if (!f.isAbsolute()) f = new File(base, keystore);
- // signer.setKeystore(f);
- // } else {
- // error("Signing requires a keystore");
- // return null;
- // }
- //
- // String alias = (String) parsed.get("alias");
- // if (alias != null) {
- // signer.setAlias(alias);
- // } else {
- // error("Signing requires an alias for the key");
- // return null;
- // }
- // return signer;
- // }
-
- public void setBase(File file) {
- super.setBase(file);
- getProperties().put("project.dir", getBase().getAbsolutePath());
- }
-
- /**
- * Set the classpath for this analyzer by file.
- *
- * @param classpath
- * @throws IOException
- */
- public void setClasspath(File[] classpath) throws IOException {
- List<Jar> list = new ArrayList<Jar>();
- for (int i = 0; i < classpath.length; i++) {
- if (classpath[i].exists()) {
- Jar current = new Jar(classpath[i]);
- list.add(current);
- } else {
- error("Missing file on classpath: " + classpath[i]);
- }
- }
- for (Iterator<Jar> i = list.iterator(); i.hasNext();) {
- addClasspath(i.next());
- }
- }
-
- public void setClasspath(Jar[] classpath) {
- for (int i = 0; i < classpath.length; i++) {
- addClasspath(classpath[i]);
- }
- }
-
- public void setClasspath(String[] classpath) {
- for (int i = 0; i < classpath.length; i++) {
- Jar jar = getJarFromName(classpath[i], " setting classpath");
- if (jar != null)
- addClasspath(jar);
- }
- }
-
- /**
- * Set the JAR file we are going to work in. This will read the JAR in
- * memory.
- *
- * @param jar
- * @return
- * @throws IOException
- */
- public Jar setJar(File jar) throws IOException {
- Jar jarx = new Jar(jar);
- addClose(jarx);
- return setJar(jarx);
- }
-
- /**
- * Set the JAR directly we are going to work on.
- *
- * @param jar
- * @return
- */
- public Jar setJar(Jar jar) {
- this.dot = jar;
- return jar;
- }
-
- protected void begin() {
- super.begin();
-
- updateModified(getBndLastModified(), "bnd last modified");
- String doNotCopy = getProperty(DONOTCOPY);
- if (doNotCopy != null)
- Analyzer.doNotCopy = Pattern.compile(doNotCopy);
-
- verifyManifestHeadersCase(getProperties());
- }
-
- /**
- * Check if the given class or interface name is contained in the jar.
- *
- * @param interfaceName
- * @return
- */
- boolean checkClass(String interfaceName) {
- String path = interfaceName.replace('.', '/') + ".class";
- if (classspace.containsKey(path))
- return true;
-
- String pack = interfaceName;
- int n = pack.lastIndexOf('.');
- if (n > 0)
- pack = pack.substring(0, n);
- else
- pack = ".";
-
- return imports.containsKey(pack);
- }
-
- /**
- * Create the resource for a DS component.
- *
- * @param list
- * @param name
- * @param info
- * @throws UnsupportedEncodingException
- */
- Resource createComponentResource(String name, Map<String, String> info)
- throws IOException {
-
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- PrintWriter pw = new PrintWriter(new OutputStreamWriter(out, "UTF-8"));
- pw.println("<?xml version='1.0' encoding='utf-8'?>");
- pw.print("<component name='" + name + "'");
-
- String factory = info.get(COMPONENT_FACTORY);
- if (factory != null)
- pw.print(" factory='" + factory + "'");
-
- String immediate = info.get(COMPONENT_IMMEDIATE);
- if (immediate != null)
- pw.print(" immediate='" + immediate + "'");
-
- String enabled = info.get(COMPONENT_ENABLED);
- if (enabled != null)
- pw.print(" enabled='" + enabled + "'");
-
- pw.println(">");
-
- // Allow override of the implementation when people
- // want to choose their own name
- String impl = (String) info.get(COMPONENT_IMPLEMENTATION);
- pw.println(" <implementation class='" + (impl == null ? name : impl)
- + "'/>");
-
- String provides = info.get(COMPONENT_PROVIDE);
- boolean servicefactory = Boolean.getBoolean(info
- .get(COMPONENT_SERVICEFACTORY)
- + "");
- provides(pw, provides, servicefactory);
- properties(pw, info);
- reference(info, pw);
- pw.println("</component>");
- pw.close();
- byte[] data = out.toByteArray();
- out.close();
- return new EmbeddedResource(data, 0);
- }
-
- /**
- * Try to get a Jar from a file name/path or a url, or in last resort from
- * the classpath name part of their files.
- *
- * @param name
- * URL or filename relative to the base
- * @param from
- * Message identifying the caller for errors
- * @return null or a Jar with the contents for the name
- */
- Jar getJarFromName(String name, String from) {
- File file = new File(name);
- if (!file.isAbsolute())
- file = new File(getBase(), name);
-
- if (file.exists())
- try {
- Jar jar = new Jar(file);
- addClose(jar);
- return jar;
- } catch (Exception e) {
- error("Exception in parsing jar file for " + from + ": " + name
- + " " + e);
- }
- // It is not a file ...
- try {
- // Lets try a URL
- URL url = new URL(name);
- Jar jar = new Jar(fileName(url.getPath()));
- addClose(jar);
- URLConnection connection = url.openConnection();
- InputStream in = connection.getInputStream();
- long lastModified = connection.getLastModified();
- if (lastModified == 0)
- // We assume the worst :-(
- lastModified = System.currentTimeMillis();
- EmbeddedResource.build(jar, in, lastModified);
- in.close();
- return jar;
- } catch (IOException ee) {
- // Check if we have files on the classpath
- // that have the right name, allows us to specify those
- // names instead of the full path.
- for (Iterator<Jar> cp = getClasspath().iterator(); cp.hasNext();) {
- Jar entry = cp.next();
- if (entry.source != null && entry.source.getName().equals(name)) {
- return entry;
- }
- }
- // error("Can not find jar file for " + from + ": " + name);
- }
- return null;
- }
-
- private String fileName(String path) {
- int n = path.lastIndexOf('/');
- if (n > 0)
- return path.substring(n + 1);
- return path;
- }
-
- /**
- *
- * @param manifest
- * @throws Exception
- */
- void merge(Manifest result, Manifest old) throws IOException {
- if (old != null) {
- for (Iterator<Map.Entry<Object, Object>> e = old
- .getMainAttributes().entrySet().iterator(); e.hasNext();) {
- Map.Entry<Object, Object> entry = e.next();
- Attributes.Name name = (Attributes.Name) entry.getKey();
- String value = (String) entry.getValue();
- if (name.toString().equalsIgnoreCase("Created-By"))
- name = new Attributes.Name("Originally-Created-By");
- if (!result.getMainAttributes().containsKey(name))
- result.getMainAttributes().put(name, value);
- }
-
- // do not overwrite existing entries
- Map<String, Attributes> oldEntries = old.getEntries();
- Map<String, Attributes> newEntries = result.getEntries();
- for (Iterator<Map.Entry<String, Attributes>> e = oldEntries
- .entrySet().iterator(); e.hasNext();) {
- Map.Entry<String, Attributes> entry = e.next();
- if (!newEntries.containsKey(entry.getKey())) {
- newEntries.put(entry.getKey(), entry.getValue());
- }
- }
- }
- }
-
- /**
- * Print the Service-Component properties element
- *
- * @param pw
- * @param info
- */
- void properties(PrintWriter pw, Map<String, String> info) {
- Collection<String> properties = split(info.get(COMPONENT_PROPERTIES));
- for (Iterator<String> p = properties.iterator(); p.hasNext();) {
- String clause = p.next();
- int n = clause.indexOf('=');
- if (n <= 0) {
- error("Not a valid property in service component: " + clause);
- } else {
- String type = null;
- String name = clause.substring(0, n);
- if (name.indexOf('@') >= 0) {
- String parts[] = name.split("@");
- name = parts[1];
- type = parts[0];
- }
- String value = clause.substring(n + 1).trim();
- // TODO verify validity of name and value.
- pw.print("<property name='");
- pw.print(name);
- pw.print("'");
-
- if (type != null) {
- if (VALID_PROPERTY_TYPES.matcher(type).matches()) {
- pw.print(" type='");
- pw.print(type);
- pw.print("'");
- } else {
- warning("Invalid property type '" + type
- + "' for property " + name);
- }
- }
-
- String parts[] = value.split("\\s*(\\||\\n)\\s*");
- if (parts.length > 1) {
- pw.println(">");
- for (String part : parts) {
- pw.println(part);
- }
- pw.println("</property>");
- } else {
- pw.print(" value='");
- pw.print(parts[0]);
- pw.print("'/>");
- }
- }
- }
- }
-
- /**
- * @param pw
- * @param provides
- */
- void provides(PrintWriter pw, String provides, boolean servicefactory) {
- if (provides != null) {
- if (!servicefactory)
- pw.println(" <service>");
- else
- pw.println(" <service servicefactory='true'>");
-
- StringTokenizer st = new StringTokenizer(provides, ",");
- while (st.hasMoreTokens()) {
- String interfaceName = st.nextToken();
- pw.println(" <provide interface='" + interfaceName + "'/>");
- if (!checkClass(interfaceName))
- error("Component definition provides a class that is neither imported nor contained: "
- + interfaceName);
- }
- pw.println(" </service>");
- }
- }
-
- final static Pattern REFERENCE = Pattern.compile("([^(]+)(\\(.+\\))?");
-
- /**
- * @param info
- * @param pw
- */
-
- void reference(Map<String, String> info, PrintWriter pw) {
- Collection<String> dynamic = split(info.get(COMPONENT_DYNAMIC));
- Collection<String> optional = split(info.get(COMPONENT_OPTIONAL));
- Collection<String> multiple = split(info.get(COMPONENT_MULTIPLE));
-
- for (Iterator<Map.Entry<String, String>> r = info.entrySet().iterator(); r
- .hasNext();) {
- Map.Entry<String, String> ref = r.next();
- String referenceName = (String) ref.getKey();
- String target = null;
- String interfaceName = (String) ref.getValue();
- if (interfaceName == null || interfaceName.length() == 0) {
- error("Invalid Interface Name for references in Service Component: "
- + referenceName + "=" + interfaceName);
- }
- char c = interfaceName.charAt(interfaceName.length() - 1);
- if ("?+*~".indexOf(c) >= 0) {
- if (c == '?' || c == '*' || c == '~')
- optional.add(referenceName);
- if (c == '+' || c == '*')
- multiple.add(referenceName);
- if (c == '+' || c == '*' || c == '?')
- dynamic.add(referenceName);
- interfaceName = interfaceName.substring(0, interfaceName
- .length() - 1);
- }
-
- // TODO check if the interface is contained or imported
-
- if (referenceName.endsWith(":")) {
- if (!SET_COMPONENT_DIRECTIVES.contains(referenceName))
- error("Unrecognized directive in Service-Component header: "
- + referenceName);
- continue;
- }
-
- Matcher m = REFERENCE.matcher(interfaceName);
- if (m.matches()) {
- interfaceName = m.group(1);
- target = m.group(2);
- }
-
- if (!checkClass(interfaceName))
- error("Component definition refers to a class that is neither imported nor contained: "
- + interfaceName);
-
- pw.print(" <reference name='" + referenceName + "' interface='"
- + interfaceName + "'");
-
- String cardinality = optional.contains(referenceName) ? "0" : "1";
- cardinality += "..";
- cardinality += multiple.contains(referenceName) ? "n" : "1";
- if (!cardinality.equals("1..1"))
- pw.print(" cardinality='" + cardinality + "'");
-
- if (Character.isLowerCase(referenceName.charAt(0))) {
- String z = referenceName.substring(0, 1).toUpperCase()
- + referenceName.substring(1);
- pw.print(" bind='set" + z + "'");
- // TODO Verify that the methods exist
-
- // TODO ProSyst requires both a bind and unbind :-(
- // if ( dynamic.contains(referenceName) )
- pw.print(" unbind='unset" + z + "'");
- // TODO Verify that the methods exist
- }
- if (dynamic.contains(referenceName)) {
- pw.print(" policy='dynamic'");
- }
-
- if (target != null) {
- Filter filter = new Filter(target);
- if (filter.verify() == null)
- pw.print(" target='" + filter.toString() + "'");
- else
- error("Target for " + referenceName
- + " is not a correct filter: " + target + " "
- + filter.verify());
- }
- pw.println("/>");
- }
- }
-
- String stem(String name) {
- int n = name.lastIndexOf('.');
- if (n > 0)
- return name.substring(0, n);
- else
- return name;
- }
-
- /**
- * Bnd is case sensitive for the instructions so we better check people are
- * not using an invalid case. We do allow this to set headers that should
- * not be processed by us but should be used by the framework.
- *
- * @param properties
- * Properties to verify.
- */
-
- void verifyManifestHeadersCase(Properties properties) {
- for (Iterator<Object> i = properties.keySet().iterator(); i.hasNext();) {
- String header = (String) i.next();
- for (int j = 0; j < headers.length; j++) {
- if (!headers[j].equals(header)
- && headers[j].equalsIgnoreCase(header)) {
- warning("Using a standard OSGi header with the wrong case (bnd is case sensitive!), using: "
- + header + " and expecting: " + headers[j]);
- break;
- }
- }
- }
- }
-
- /**
- * We will add all exports to the imports unless there is a -noimport
- * directive specified on an export. This directive is skipped for the
- * manifest.
- *
- * We also remove any version parameter so that augmentImports can do the
- * version policy.
- *
- */
- Map<String, Map<String, String>> addExportsToImports(
- Map<String, Map<String, String>> exports) {
- Map<String, Map<String, String>> importsFromExports = newHashMap();
- for (Map.Entry<String, Map<String, String>> packageEntry : exports
- .entrySet()) {
- String packageName = packageEntry.getKey();
- Map<String, String> parameters = packageEntry.getValue();
- String noimport = (String) parameters.get(NO_IMPORT_DIRECTIVE);
- if (noimport == null || !noimport.equalsIgnoreCase("true")) {
- if (parameters.containsKey("version")) {
- parameters = newMap(parameters);
- parameters.remove("version");
- }
- importsFromExports.put(packageName, parameters);
- }
- }
- return importsFromExports;
- }
-
- /**
- * Create the imports/exports by parsing
- *
- * @throws IOException
- */
- void analyzeClasspath() throws IOException {
- classpathExports = newHashMap();
- for (Iterator<Jar> c = getClasspath().iterator(); c.hasNext();) {
- Jar current = c.next();
- checkManifest(current);
- for (Iterator<String> j = current.getDirectories().keySet()
- .iterator(); j.hasNext();) {
- String dir = j.next();
- Resource resource = current.getResource(dir + "/packageinfo");
- if (resource != null) {
- InputStream in = resource.openInputStream();
- String version = parsePackageInfo(in);
- in.close();
- setPackageInfo(dir, "version", version);
- }
- }
- }
- }
-
- /**
- *
- * @param jar
- */
- void checkManifest(Jar jar) {
- try {
- Manifest m = jar.getManifest();
- if (m != null) {
- String exportHeader = m.getMainAttributes().getValue(
- EXPORT_PACKAGE);
- if (exportHeader != null) {
- Map<String, Map<String, String>> exported = parseHeader(exportHeader);
- if (exported != null)
- classpathExports.putAll(exported);
- }
- }
- } catch (Exception e) {
- warning("Erroneous Manifest for " + jar + " " + e);
- }
- }
-
- /**
- * Find some more information about imports in manifest and other places.
- */
- void augmentImports() {
- for (String packageName : imports.keySet()) {
- setProperty(CURRENT_PACKAGE, packageName);
- try {
- Map<String, String> importAttributes = imports.get(packageName);
- Map<String, String> exporterAttributes = classpathExports
- .get(packageName);
- if (exporterAttributes == null)
- exporterAttributes = exports.get(packageName);
-
- if (exporterAttributes != null) {
- augmentVersion(importAttributes, exporterAttributes);
- augmentMandatory(importAttributes, exporterAttributes);
- if (exporterAttributes.containsKey(IMPORT_DIRECTIVE))
- importAttributes.put(IMPORT_DIRECTIVE,
- exporterAttributes.get(IMPORT_DIRECTIVE));
- }
-
- // Convert any attribute values that have macros.
- for (String key : importAttributes.keySet()) {
- String value = importAttributes.get(key);
- if (value.indexOf('$') >= 0) {
- value = getReplacer().process(value);
- importAttributes.put(key, value);
- }
- }
-
- // You can add a remove-attribute: directive with a regular
- // expression for attributes that need to be removed. We also
- // remove all attributes that have a value of !. This allows
- // you to use macros with ${if} to remove values.
- String remove = importAttributes
- .remove(REMOVE_ATTRIBUTE_DIRECTIVE);
- Instruction removeInstr = null;
-
- if (remove != null)
- removeInstr = Instruction.getPattern(remove);
-
- for (Iterator<Map.Entry<String, String>> i = importAttributes
- .entrySet().iterator(); i.hasNext();) {
- Map.Entry<String, String> entry = i.next();
- if (entry.getValue().equals("!"))
- i.remove();
- else if (removeInstr != null
- && removeInstr.matches((String) entry.getKey()))
- i.remove();
- else {
- // Not removed ...
- }
- }
-
- } finally {
- unsetProperty(CURRENT_PACKAGE);
- }
- }
- }
-
- /**
- * If we use an import with mandatory attributes we better all use them
- *
- * @param currentAttributes
- * @param exporter
- */
- private void augmentMandatory(Map<String, String> currentAttributes,
- Map<String, String> exporter) {
- String mandatory = (String) exporter.get("mandatory:");
- if (mandatory != null) {
- String[] attrs = mandatory.split("\\s*,\\s*");
- for (int i = 0; i < attrs.length; i++) {
- if (!currentAttributes.containsKey(attrs[i]))
- currentAttributes.put(attrs[i], exporter.get(attrs[i]));
- }
- }
- }
-
- /**
- * Check if we can augment the version from the exporter.
- *
- * We allow the version in the import to specify a @ which is replaced with
- * the exporter's version.
- *
- * @param currentAttributes
- * @param exporter
- */
- private void augmentVersion(Map<String, String> currentAttributes,
- Map<String, String> exporter) {
-
- String exportVersion = (String) exporter.get("version");
- if (exportVersion == null)
- exportVersion = (String) exporter.get("specification-version");
- if (exportVersion == null)
- return;
-
- exportVersion = cleanupVersion(exportVersion);
-
- setProperty("@", exportVersion);
-
- String importRange = currentAttributes.get("version");
- if (importRange != null) {
- importRange = cleanupVersion(importRange);
- importRange = getReplacer().process(importRange);
- } else
- importRange = getVersionPolicy();
-
- unsetProperty("@");
-
- // See if we can borrow the version
- // we mist replace the ${@} with the version we
- // found this can be useful if you want a range to start
- // with the found version.
- currentAttributes.put("version", importRange);
- }
-
- /**
- * Add the uses clauses
- *
- * @param exports
- * @param uses
- * @throws MojoExecutionException
- */
- void doUses(Map<String, Map<String, String>> exports,
- Map<String, Set<String>> uses,
- Map<String, Map<String, String>> imports) {
- if ("true".equalsIgnoreCase(getProperty(NOUSES)))
- return;
-
- for (Iterator<String> i = exports.keySet().iterator(); i.hasNext();) {
- String packageName = i.next();
- setProperty(CURRENT_PACKAGE, packageName);
- try {
- Map<String, String> clause = exports.get(packageName);
- String override = clause.get(USES_DIRECTIVE);
- if (override == null)
- override = USES_USES;
-
- Set<String> usedPackages = uses.get(packageName);
- if (usedPackages != null) {
- // Only do a uses on exported or imported packages
- // and uses should also not contain our own package
- // name
- Set<String> sharedPackages = new HashSet<String>();
- sharedPackages.addAll(imports.keySet());
- sharedPackages.addAll(exports.keySet());
- usedPackages.retainAll(sharedPackages);
- usedPackages.remove(packageName);
-
- StringBuffer sb = new StringBuffer();
- String del = "";
- for (Iterator<String> u = usedPackages.iterator(); u
- .hasNext();) {
- String usedPackage = u.next();
- if (!usedPackage.startsWith("java.")) {
- sb.append(del);
- sb.append(usedPackage);
- del = ",";
- }
- }
- if (override.indexOf('$') >= 0) {
- setProperty(CURRENT_USES, sb.toString());
- override = getReplacer().process(override);
- unsetProperty(CURRENT_USES);
- } else
- // This is for backward compatibility 0.0.287
- // can be deprecated over time
- override = override
- .replaceAll(USES_USES, sb.toString()).trim();
- if (override.endsWith(","))
- override = override.substring(0, override.length() - 1);
- if (override.startsWith(","))
- override = override.substring(1);
- if (override.length() > 0) {
- clause.put("uses:", override);
- }
- }
- } finally {
- unsetProperty(CURRENT_PACKAGE);
- }
- }
- }
-
- /**
- * Transitively remove all elemens from unreachable through the uses link.
- *
- * @param name
- * @param unreachable
- */
- void removeTransitive(String name, Set<String> unreachable) {
- if (!unreachable.contains(name))
- return;
-
- unreachable.remove(name);
-
- Set<String> ref = uses.get(name);
- if (ref != null) {
- for (Iterator<String> r = ref.iterator(); r.hasNext();) {
- String element = (String) r.next();
- removeTransitive(element, unreachable);
- }
- }
- }
-
- /**
- * Helper method to set the package info
- *
- * @param dir
- * @param key
- * @param value
- */
- void setPackageInfo(String dir, String key, String value) {
- if (value != null) {
- String pack = dir.replace('/', '.');
- Map<String, String> map = classpathExports.get(pack);
- if (map == null) {
- map = new HashMap<String, String>();
- classpathExports.put(pack, map);
- }
- map.put(key, value);
- }
- }
-
- public void close() {
- super.close();
- if (dot != null)
- dot.close();
-
- if (classpath != null)
- for (Iterator<Jar> j = classpath.iterator(); j.hasNext();) {
- Jar jar = j.next();
- jar.close();
- }
- }
-
- /**
- * Findpath looks through the contents of the JAR and finds paths that end
- * with the given regular expression
- *
- * ${findpath (; reg-expr (; replacement)? )? }
- *
- * @param args
- * @return
- */
- public String _findpath(String args[]) {
- return findPath("findpath", args, true);
- }
-
- public String _findname(String args[]) {
- return findPath("findname", args, false);
- }
-
- String findPath(String name, String[] args, boolean fullPathName) {
- if (args.length > 3) {
- warning("Invalid nr of arguments to " + name + " "
- + Arrays.asList(args) + ", syntax: ${" + name
- + " (; reg-expr (; replacement)? )? }");
- return null;
- }
-
- String regexp = ".*";
- String replace = null;
-
- switch (args.length) {
- case 3:
- replace = args[2];
- case 2:
- regexp = args[1];
- }
- StringBuffer sb = new StringBuffer();
- String del = "";
-
- Pattern expr = Pattern.compile(regexp);
- for (Iterator<String> e = dot.getResources().keySet().iterator(); e
- .hasNext();) {
- String path = e.next();
- if (!fullPathName) {
- int n = path.lastIndexOf('/');
- if (n >= 0) {
- path = path.substring(n + 1);
- }
- }
-
- Matcher m = expr.matcher(path);
- if (m.matches()) {
- if (replace != null)
- path = m.replaceAll(replace);
-
- sb.append(del);
- sb.append(path);
- del = ", ";
- }
- }
- return sb.toString();
- }
-
- public void putAll(Map<String, String> additional, boolean force) {
- for (Iterator<Map.Entry<String, String>> i = additional.entrySet()
- .iterator(); i.hasNext();) {
- Map.Entry<String, String> entry = i.next();
- if (force || getProperties().get(entry.getKey()) == null)
- setProperty((String) entry.getKey(), (String) entry.getValue());
- }
- }
-
- boolean firstUse = true;
-
- public List<Jar> getClasspath() {
- if (firstUse) {
- firstUse = false;
- String cp = getProperty(CLASSPATH);
- if (cp != null)
- for (String s : split(cp)) {
- Jar jar = getJarFromName(s, "getting classpath");
- if (jar != null)
- addClasspath(jar);
- }
- }
- return classpath;
- }
-
- public void addClasspath(Jar jar) {
- if (isPedantic() && jar.getResources().isEmpty())
- warning("There is an empty jar or directory on the classpath: "
- + jar.getName());
-
- classpath.add(jar);
- }
-
- public void addClasspath(File cp) throws IOException {
- if (!cp.exists())
- warning("File on classpath that does not exist: " + cp);
- Jar jar = new Jar(cp);
- addClose(jar);
- classpath.add(jar);
- }
-
- public void clear() {
- classpath.clear();
- }
-
- public Jar getTarget() {
- return dot;
- }
-
- public Map<String, Clazz> analyzeBundleClasspath(Jar dot,
- Map<String, Map<String, String>> bundleClasspath,
- Map<String, Map<String, String>> contained,
- Map<String, Map<String, String>> referred,
- Map<String, Set<String>> uses) throws IOException {
- Map<String, Clazz> classSpace = new HashMap<String, Clazz>();
-
- if (bundleClasspath.isEmpty()) {
- analyzeJar(dot, "", classSpace, contained, referred, uses);
- } else {
- for (String path : bundleClasspath.keySet()) {
- if (path.equals(".")) {
- analyzeJar(dot, "", classSpace, contained, referred, uses);
- continue;
- }
- //
- // There are 3 cases:
- // - embedded JAR file
- // - directory
- // - error
- //
-
- Resource resource = dot.getResource(path);
- if (resource != null) {
- try {
- Jar jar = new Jar(path);
- addClose(jar);
- EmbeddedResource.build(jar, resource);
- analyzeJar(jar, "", classSpace, contained, referred,
- uses);
- } catch (Exception e) {
- warning("Invalid bundle classpath entry: " + path + " "
- + e);
- }
- } else {
- if (dot.getDirectories().containsKey(path)) {
- analyzeJar(dot, path + '/', classSpace, contained, referred,
- uses);
- } else {
- warning("No sub JAR or directory " + path);
- }
- }
- }
- }
- return classSpace;
- }
-
- /**
- * We traverse through all the classes that we can find and calculate the
- * contained and referred set and uses. This method ignores the Bundle
- * classpath.
- *
- * @param jar
- * @param contained
- * @param referred
- * @param uses
- * @throws IOException
- */
- private void analyzeJar(Jar jar, String prefix,
- Map<String, Clazz> classSpace,
- Map<String, Map<String, String>> contained,
- Map<String, Map<String, String>> referred,
- Map<String, Set<String>> uses) throws IOException {
-
- next: for (String path : jar.getResources().keySet()) {
- if (path.startsWith(prefix)) {
- String relativePath = path.substring(prefix.length());
- String pack = getPackage(relativePath);
-
- if (pack != null && !contained.containsKey(pack)) {
- if (!isMetaData(relativePath)) {
-
- Map<String, String> map = new LinkedHashMap<String, String>();
- contained.put(pack, map);
- Resource pinfo = jar.getResource(prefix
- + pack.replace('.', '/') + "/packageinfo");
- if (pinfo != null) {
- InputStream in = pinfo.openInputStream();
- String version = parsePackageInfo(in);
- in.close();
- if (version != null)
- map.put("version", version);
- }
- }
- }
-
- if (path.endsWith(".class")) {
- Resource resource = jar.getResource(path);
- Clazz clazz;
-
- try {
- InputStream in = resource.openInputStream();
- clazz = new Clazz(relativePath, in);
- in.close();
- } catch (Throwable e) {
- error("Invalid class file: " + relativePath, e);
- e.printStackTrace();
- continue next;
- }
-
- String calculatedPath = clazz.getClassName() + ".class";
- if (!calculatedPath.equals(relativePath))
- error("Class in different directory than declared. Path from class name is "
- + calculatedPath
- + " but the path in the jar is "
- + relativePath
- + " from " + jar);
-
- classSpace.put(relativePath, clazz);
- referred.putAll(clazz.getReferred());
-
- // Add all the used packages
- // to this package
- Set<String> t = uses.get(pack);
- if (t == null)
- uses.put(pack, t = new LinkedHashSet<String>());
- t.addAll(clazz.getReferred().keySet());
- t.remove(pack);
- }
- }
- }
- }
-
- /**
- * Clean up version parameters. Other builders use more fuzzy definitions of
- * the version syntax. This method cleans up such a version to match an OSGi
- * version.
- *
- * @param VERSION_STRING
- * @return
- */
- static Pattern fuzzyVersion = Pattern
- .compile(
- "(\\d+)(\\.(\\d+)(\\.(\\d+))?)?([^a-zA-Z0-9](.*))?",
- Pattern.DOTALL);
- static Pattern fuzzyVersionRange = Pattern
- .compile(
- "(\\(|\\[)\\s*([-\\da-zA-Z.]+)\\s*,\\s*([-\\da-zA-Z.]+)\\s*(\\]|\\))",
- Pattern.DOTALL);
- static Pattern fuzzyModifier = Pattern.compile("(\\d+[.-])*(.*)",
- Pattern.DOTALL);
-
- static Pattern nummeric = Pattern.compile("\\d*");
-
- static public String cleanupVersion(String version) {
- if (Verifier.VERSIONRANGE.matcher(version).matches())
- return version;
-
- Matcher m = fuzzyVersionRange.matcher(version);
- if (m.matches()) {
- String prefix = m.group(1);
- String first = m.group(2);
- String last = m.group(3);
- String suffix = m.group(4);
- return prefix + cleanupVersion(first) + "," + cleanupVersion(last)
- + suffix;
- } else {
- m = fuzzyVersion.matcher(version);
- if (m.matches()) {
- StringBuffer result = new StringBuffer();
- String major = m.group(1);
- String minor = m.group(3);
- String micro = m.group(5);
- String qualifier = m.group(7);
-
- if (major != null) {
- result.append(major);
- if (minor != null) {
- result.append(".");
- result.append(minor);
- if (micro != null) {
- result.append(".");
- result.append(micro);
- if (qualifier != null) {
- result.append(".");
- cleanupModifier(result, qualifier);
- }
- } else if (qualifier != null) {
- result.append(".0.");
- cleanupModifier(result, qualifier);
- }
- } else if (qualifier != null) {
- result.append(".0.0.");
- cleanupModifier(result, qualifier);
- }
- return result.toString();
- }
- }
- }
- return version;
- }
-
- static void cleanupModifier(StringBuffer result, String modifier) {
- Matcher m = fuzzyModifier.matcher(modifier);
- if (m.matches())
- modifier = m.group(2);
-
- for (int i = 0; i < modifier.length(); i++) {
- char c = modifier.charAt(i);
- if ((c >= '0' && c <= '9') || (c >= 'a' && c <= 'z')
- || (c >= 'A' && c <= 'Z') || c == '_' || c == '-')
- result.append(c);
- }
- }
-
- /**
- * Decide if the package is a metadata package.
- *
- * @param pack
- * @return
- */
- boolean isMetaData(String pack) {
- for (int i = 0; i < METAPACKAGES.length; i++) {
- if (pack.startsWith(METAPACKAGES[i]))
- return true;
- }
- return false;
- }
-
- public String getPackage(String clazz) {
- int n = clazz.lastIndexOf('/');
- if (n < 0)
- return ".";
- return clazz.substring(0, n).replace('/', '.');
- }
-
- //
- // We accept more than correct OSGi versions because in a later
- // phase we actually cleanup maven versions. But it is a bit yucky
- //
- static String parsePackageInfo(InputStream jar) throws IOException {
- try {
- Properties p = new Properties();
- p.load(jar);
- jar.close();
- if (p.containsKey("version")) {
- return p.getProperty("version");
- }
- } catch (Exception e) {
- e.printStackTrace();
- }
- return null;
- }
-
- public String getVersionPolicy() {
- return getProperty(VERSIONPOLICY, "${version;==;${@}}");
- }
-
- /**
- * The extends macro traverses all classes and returns a list of class names
- * that extend a base class.
- */
-
- static String _classesHelp = "${classes;'implementing'|'extending'|'importing'|'named'|'version'|'any';<pattern>}, Return a list of class fully qualified class names that extend/implement/import any of the contained classes matching the pattern\n";
-
- public String _classes(String args[]) {
- // Macro.verifyCommand(args, _classesHelp, new
- // Pattern[]{null,Pattern.compile("(implementing|implements|extending|extends|importing|imports|any)"),
- // null}, 3,3);
- Set<Clazz> matched = new HashSet<Clazz>(classspace.values());
- for (int i = 1; i < args.length; i += 2) {
- if (args.length < i + 1)
- throw new IllegalArgumentException(
- "${classes} macro must have odd number of arguments. "
- + _classesHelp);
-
- String typeName = args[i];
- Clazz.QUERY type = null;
- if (typeName.equals("implementing")
- || typeName.equals("implements"))
- type = Clazz.QUERY.IMPLEMENTS;
- else if (typeName.equals("extending") || typeName.equals("extends"))
- type = Clazz.QUERY.EXTENDS;
- else if (typeName.equals("importing") || typeName.equals("imports"))
- type = Clazz.QUERY.IMPORTS;
- else if (typeName.equals("all"))
- type = Clazz.QUERY.ANY;
- else if (typeName.equals("version"))
- type = Clazz.QUERY.VERSION;
- else if (typeName.equals("named"))
- type = Clazz.QUERY.NAMED;
-
- if (type == null)
- throw new IllegalArgumentException(
- "${classes} has invalid type: " + typeName + ". "
- + _classesHelp);
- // The argument is declared as a dotted name but the classes
- // use a slashed named. So convert the name before we make it a
- // instruction.
- String pattern = args[i + 1].replace('.', '/');
- Instruction instr = Instruction.getPattern(pattern);
-
- for (Iterator<Clazz> c = matched.iterator(); c.hasNext();) {
- Clazz clazz = c.next();
- if (!clazz.is(type, instr, classspace))
- c.remove();
- }
- }
- if (matched.isEmpty())
- return "";
-
- return join(matched);
- }
-
- /**
- * Get the exporter of a package ...
- */
-
- public String _exporters(String args[]) throws Exception {
- Macro
- .verifyCommand(
- args,
- "${exporters;<packagename>}, returns the list of jars that export the given package",
- null, 2, 2);
- StringBuilder sb = new StringBuilder();
- String del = "";
- String pack = args[1].replace('.', '/');
- for (Jar jar : classpath) {
- if (jar.getDirectories().containsKey(pack)) {
- sb.append(del);
- sb.append(jar.getName());
- }
- }
- return sb.toString();
- }
-
- public Map<String, Clazz> getClassspace() {
- return classspace;
- }
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java b/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
deleted file mode 100644
index 84c35e6..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Builder.java
+++ /dev/null
@@ -1,1131 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.security.*;
-import java.security.cert.*;
-import java.security.spec.*;
-import java.util.*;
-import java.util.jar.*;
-import java.util.regex.*;
-import java.util.zip.*;
-
-import aQute.bnd.make.*;
-import aQute.lib.signing.*;
-
-/**
- * Include-Resource: ( [name '=' ] file )+
- *
- * Private-Package: package-decl ( ',' package-decl )*
- *
- * Export-Package: package-decl ( ',' package-decl )*
- *
- * Import-Package: package-decl ( ',' package-decl )*
- *
- * @version $Revision: 1.4 $
- */
-public class Builder extends Analyzer {
- private static final int SPLIT_MERGE_LAST = 1;
- private static final int SPLIT_MERGE_FIRST = 2;
- private static final int SPLIT_ERROR = 3;
- private static final int SPLIT_FIRST = 4;
- private static final int SPLIT_DEFAULT = 0;
-
- List<File> sourcePath = new ArrayList<File>();
- Pattern NAME_URL = Pattern
- .compile("(.*)(http://.*)");
-
- Make make = new Make(this);
- private KeyStore keystore;
-
- public Builder(Processor parent) {
- super(parent);
- }
-
- public Builder() {
- }
-
- public Jar build() throws Exception {
- if (getProperty(NOPE) != null)
- return null;
-
- String sub = getProperty(SUB);
- if (sub != null && sub.trim().length() > 0)
- error("Specified "
- + SUB
- + " but calls build() instead of builds() (might be a programmer error)");
-
- if (getProperty(CONDUIT) != null)
- error("Specified "
- + CONDUIT
- + " but calls build() instead of builds() (might be a programmer error");
-
- dot = new Jar("dot");
- addClose(dot);
- try {
- long modified = Long.parseLong(getProperty("base.modified"));
- dot.updateModified(modified, "Base modified");
- } catch (Exception e) {
- }
-
- doExpand(dot);
- doIncludeResources(dot);
-
- doConditional(dot);
-
- // NEW!
- // Check if we override the calculation of the
- // manifest. We still need to calculated it because
- // we need to have analyzed the classpath.
-
- Manifest manifest = calcManifest();
-
- String mf = getProperty(MANIFEST);
- if (mf != null) {
- File mff = getFile(mf);
- if (mff.isFile()) {
- try {
- InputStream in = new FileInputStream(mff);
- manifest = new Manifest(in);
- in.close();
- } catch (Exception e) {
- error(MANIFEST + " while reading manifest file", e);
- }
- } else {
- error(MANIFEST + ", no such file " + mf);
- }
- }
-
- dot.setManifest(manifest);
-
- // This must happen after we analyzed so
- // we know what it is on the classpath
- addSources(dot);
- if (getProperty(POM) != null)
- doPom(dot);
-
- doVerify(dot);
-
- if (dot.getResources().isEmpty())
- error("The JAR is empty");
-
- dot.updateModified(lastModified(), "Last Modified Processor");
- dot.setName(getBsn());
-
- sign(dot);
- return dot;
- }
-
- /**
- * Sign the jar file.
- *
- * -sign : <alias> [ ';' 'password:=' <password> ] [ ';' 'keystore:='
- * <keystore> ] [ ';' 'sign-password:=' <pw> ] ( ',' ... )*
- *
- * @return
- */
-
- void sign(Jar jar) throws Exception {
- String signing = getProperty("-sign");
- if (signing == null)
- return;
-
- trace("Signing %s, with %s", getBsn(), signing);
-
- Map<String, Map<String, String>> infos = parseHeader(signing);
- for (Map.Entry<String, Map<String, String>> entry : infos.entrySet()) {
- String alias = entry.getKey();
- String keystoreLocation = entry.getValue().get(
- KEYSTORE_LOCATION_DIRECTIVE);
- String keystoreProvider = entry.getValue().get(
- KEYSTORE_PROVIDER_DIRECTIVE);
- String password = entry.getValue().get(KEYSTORE_PASSWORD_DIRECTIVE);
- String signpassword = entry.getValue().get(SIGN_PASSWORD_DIRECTIVE);
- KeyStore keystore = getKeystore(keystoreLocation, keystoreProvider,
- password);
- if (keystore == null) {
- error(
- "Cannot find keystore to sign bundle: location=%s, provider=%s",
- keystoreLocation, keystoreProvider);
- } else {
- if (signpassword == null && !"-none".equals(signpassword))
- signpassword = password;
-
- X509Certificate chain[] = getChain(keystore, alias);
- if (chain == null) {
- error(
- "Trying to sign bundle but no signing certificate found: %s",
- alias);
- continue;
- }
-
- try {
- Key key = keystore.getKey(alias,
- (signpassword == null ? null : signpassword
- .toCharArray()));
- KeyFactory keyFactory = KeyFactory.getInstance(key
- .getAlgorithm());
- KeySpec keySpec = keyFactory.getKeySpec(key,
- RSAPrivateKeySpec.class);
- PrivateKey privateKey = keyFactory.generatePrivate(keySpec);
-
- JarSigner signer = new JarSigner(alias, privateKey, chain);
- signer.signJar(jar);
-
- } catch (UnrecoverableKeyException uke) {
- error(
- "Cannot get key to sign, likely invalid password: %s, for %s : %s",
- signpassword, alias, uke);
- }
- }
- }
- }
-
- X509Certificate[] getChain(KeyStore keystore, String alias)
- throws Exception {
- java.security.cert.Certificate[] chain = keystore
- .getCertificateChain(alias);
- X509Certificate certChain[] = new X509Certificate[chain.length];
-
- CertificateFactory cf = CertificateFactory.getInstance("X.509");
- for (int count = 0; count < chain.length; count++) {
- ByteArrayInputStream certIn = new ByteArrayInputStream(chain[count]
- .getEncoded());
- X509Certificate cert = (X509Certificate) cf
- .generateCertificate(certIn);
- certChain[count] = cert;
- }
- return certChain;
- }
-
- KeyStore getKeystore(String keystoreLocation, String keystoreProvider,
- String password) throws Exception {
- if (keystoreLocation == null) {
- return getKeystore();
- }
- if (keystoreProvider == null)
- keystoreProvider = "JKS";
-
- KeyStore keystore = KeyStore.getInstance(keystoreProvider);
- FileInputStream in = new FileInputStream(keystoreLocation);
- try {
- keystore.load(in, password == null ? null : password.toCharArray());
- } finally {
- in.close();
- }
- return keystore;
- }
-
- KeyStore getKeystore() throws Exception {
- if (keystore != null) {
- return keystore;
- }
-
- Map<String, Map<String, String>> header = parseHeader(getProperty(
- "-keystore", "../cnf/keystore"));
- if (header.size() == 0) {
- error("Keystore needed but no -keystore specified");
- return null;
- }
-
- if (header.size() > 1) {
- warning("Multiple keystores specified, can only specify one: %s",
- header);
- }
- for (Map.Entry<String, Map<String, String>> entry : header.entrySet()) {
- return keystore = getKeystore(entry.getKey(), entry.getValue().get(
- "provider:"), entry.getValue().get("password:"));
- }
- return null;
- }
-
- public boolean hasSources() {
- return isTrue(getProperty(SOURCES));
- }
-
- protected String getImportPackages() {
- String ip = super.getImportPackages();
- if (ip != null)
- return ip;
-
- return "*";
- }
-
- private void doConditional(Jar dot) throws IOException {
- Map<String, Map<String, String>> conditionals = getHeader(CONDITIONAL_PACKAGE);
- int size;
- do {
- size = dot.getDirectories().size();
- analyze();
- analyzed = false;
- Map<String, Map<String, String>> imports = getImports();
-
- // Match the packages specified in conditionals
- // against the imports. Any match must become a
- // Private-Package
- Map<String, Map<String, String>> filtered = merge(
- CONDITIONAL_PACKAGE, conditionals, imports,
- new HashSet<String>(), null);
-
- // Imports can also specify a private import. These
- // packages must also be copied to the bundle
- for (Map.Entry<String, Map<String, String>> entry : getImports()
- .entrySet()) {
- String type = entry.getValue().get("import:");
- if (type != null && type.equals("private"))
- filtered.put(entry.getKey(), entry.getValue());
- }
-
- // remove existing packages to prevent merge errors
- filtered.keySet().removeAll(dot.getPackages());
- doExpand(dot, CONDITIONAL_PACKAGE + " Private imports",
- replaceWitInstruction(filtered, CONDITIONAL_PACKAGE), false);
- } while (dot.getDirectories().size() > size);
- analyzed = true;
- }
-
- /**
- * Intercept the call to analyze and cleanup versions after we have analyzed
- * the setup. We do not want to cleanup if we are going to verify.
- */
-
- public void analyze() throws IOException {
- super.analyze();
- cleanupVersion(imports);
- cleanupVersion(exports);
- String version = getProperty(BUNDLE_VERSION);
- if (version != null)
- setProperty(BUNDLE_VERSION, cleanupVersion(version));
- }
-
- public void cleanupVersion(Map<String, Map<String, String>> mapOfMap) {
- for (Iterator<Map.Entry<String, Map<String, String>>> e = mapOfMap
- .entrySet().iterator(); e.hasNext();) {
- Map.Entry<String, Map<String, String>> entry = e.next();
- Map<String, String> attributes = entry.getValue();
- if (attributes.containsKey("version")) {
- attributes.put("version", cleanupVersion(attributes
- .get("version")));
- }
- }
- }
-
- /**
- *
- */
- private void addSources(Jar dot) {
- if (!hasSources())
- return;
-
- Set<String> packages = new HashSet<String>();
-
- try {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- getProperties().store(out, "Generated by BND, at " + new Date());
- dot.putResource("OSGI-OPT/bnd.bnd", new EmbeddedResource(out
- .toByteArray(), 0));
- out.close();
- } catch (Exception e) {
- error("Can not embed bnd file in JAR: " + e);
- }
-
- for (Iterator<String> cpe = classspace.keySet().iterator(); cpe
- .hasNext();) {
- String path = cpe.next();
- path = path.substring(0, path.length() - ".class".length())
- + ".java";
- String pack = getPackage(path).replace('.', '/');
- if (pack.length() > 1)
- pack = pack + "/";
- boolean found = false;
- String[] fixed = { "packageinfo", "package.html",
- "module-info.java", "package-info.java" };
- for (Iterator<File> i = getSourcePath().iterator(); i.hasNext();) {
- File root = i.next();
- File f = getFile(root, path);
- if (f.exists()) {
- found = true;
- if (!packages.contains(pack)) {
- packages.add(pack);
- File bdir = getFile(root, pack);
- for (int j = 0; j < fixed.length; j++) {
- File ff = getFile(bdir, fixed[j]);
- if (ff.isFile()) {
- dot.putResource("OSGI-OPT/src/" + pack
- + fixed[j], new FileResource(ff));
- }
- }
- }
- dot
- .putResource("OSGI-OPT/src/" + path,
- new FileResource(f));
- }
- }
- if (!found) {
- for (Jar jar : classpath) {
- Resource resource = jar.getResource(path);
- if (resource != null) {
- dot.putResource("OSGI-OPT/src", resource);
- } else {
- resource = jar.getResource("OSGI-OPT/src/" + path);
- if (resource != null) {
- dot.putResource("OSGI-OPT/src", resource);
- }
- }
- }
- }
- if (getSourcePath().isEmpty())
- warning("Including sources but " + SOURCEPATH
- + " does not contain any source directories ");
- // TODO copy from the jars where they came from
- }
- }
-
- boolean firstUse = true;
-
- public Collection<File> getSourcePath() {
- if (firstUse) {
- firstUse = false;
- String sp = getProperty(SOURCEPATH);
- if (sp != null) {
- Map<String, Map<String, String>> map = parseHeader(sp);
- for (Iterator<String> i = map.keySet().iterator(); i.hasNext();) {
- String file = i.next();
- if (!isDuplicate(file)) {
- File f = getFile(file);
- if (!f.isDirectory()) {
- error("Adding a sourcepath that is not a directory: "
- + f);
- } else {
- sourcePath.add(f);
- }
- }
- }
- }
- }
- return sourcePath;
- }
-
- private void doVerify(Jar dot) throws Exception {
- Verifier verifier = new Verifier(dot, getProperties());
- verifier.setPedantic(isPedantic());
-
- // Give the verifier the benefit of our analysis
- // prevents parsing the files twice
- verifier.setClassSpace(classspace, contained, referred, uses);
- verifier.verify();
- getInfo(verifier);
- }
-
- private void doExpand(Jar jar) throws IOException {
- if (getClasspath().size() == 0
- && (getProperty(EXPORT_PACKAGE) != null || getProperty(PRIVATE_PACKAGE) != null))
- warning("Classpath is empty. Private-Package and Export-Package can only expand from the classpath when there is one");
-
- Map<Instruction, Map<String, String>> all = newMap();
-
- all.putAll(replaceWitInstruction(getHeader(PRIVATE_PACKAGE),
- PRIVATE_PACKAGE));
-
- all.putAll(replaceWitInstruction(getHeader(EXPORT_PACKAGE),
- EXPORT_PACKAGE));
-
- if (isTrue(getProperty(Constants.UNDERTEST))) {
- all.putAll(replaceWitInstruction(parseHeader(getProperty(
- Constants.TESTPACKAGES, "test;presence:=optional")),
- TESTPACKAGES));
- }
-
- if (all.isEmpty() && !isResourceOnly()) {
- warning("Neither Export-Package, Private-Package, -testpackages is set, therefore no packages will be included");
- }
-
- doExpand(jar, "Export-Package, Private-Package, or -testpackages", all,
- true);
- }
-
- /**
- *
- * @param jar
- * @param name
- * @param instructions
- */
- private void doExpand(Jar jar, String name,
- Map<Instruction, Map<String, String>> instructions,
- boolean mandatory) {
- Set<Instruction> superfluous = removeMarkedDuplicates(instructions
- .keySet());
-
- for (Iterator<Jar> c = getClasspath().iterator(); c.hasNext();) {
- Jar now = c.next();
- doExpand(jar, instructions, now, superfluous);
- }
-
- if (mandatory && superfluous.size() > 0) {
- StringBuffer sb = new StringBuffer();
- String del = "Instructions in " + name + " that are never used: ";
- for (Iterator<Instruction> i = superfluous.iterator(); i.hasNext();) {
- Instruction p = i.next();
- sb.append(del);
- sb.append(p.getPattern());
- del = ", ";
- }
- warning(sb.toString());
- }
- }
-
- /**
- * Iterate over each directory in the class path entry and check if that
- * directory is a desired package.
- *
- * @param included
- * @param classpathEntry
- */
- private void doExpand(Jar jar,
- Map<Instruction, Map<String, String>> included, Jar classpathEntry,
- Set<Instruction> superfluous) {
-
- loop: for (Map.Entry<String, Map<String, Resource>> directory : classpathEntry
- .getDirectories().entrySet()) {
- String path = directory.getKey();
-
- if (doNotCopy.matcher(getName(path)).matches())
- continue;
-
- if (directory.getValue() == null)
- continue;
-
- String pack = path.replace('/', '.');
- Instruction instr = matches(included, pack, superfluous);
- if (instr != null) {
- // System.out.println("Pattern match: " + pack + " " +
- // instr.getPattern() + " " + instr.isNegated());
- if (!instr.isNegated()) {
- Map<String, Resource> contents = directory.getValue();
-
- // What to do with split packages? Well if this
- // directory already exists, we will check the strategy
- // and react accordingly.
- boolean overwriteResource = true;
- if (jar.hasDirectory(path)) {
- Map<String, String> directives = included.get(instr);
-
- switch (getSplitStrategy((String) directives
- .get(SPLIT_PACKAGE_DIRECTIVE))) {
- case SPLIT_MERGE_LAST:
- overwriteResource = true;
- break;
-
- case SPLIT_MERGE_FIRST:
- overwriteResource = false;
- break;
-
- case SPLIT_ERROR:
- error(diagnostic(pack, getClasspath(),
- classpathEntry.source));
- continue loop;
-
- case SPLIT_FIRST:
- continue loop;
-
- default:
- warning(diagnostic(pack, getClasspath(),
- classpathEntry.source));
- overwriteResource = false;
- break;
- }
- }
-
- jar.addDirectory(contents, overwriteResource);
-
- String key = path + "/bnd.info";
- Resource r = jar.getResource(key);
- if (r != null)
- jar.putResource(key, new PreprocessResource(this, r));
-
- if (hasSources()) {
- String srcPath = "OSGI-INF/src/" + path;
- Map<String, Resource> srcContents = classpathEntry
- .getDirectories().get(srcPath);
- if (srcContents != null) {
- jar.addDirectory(srcContents, overwriteResource);
- }
- }
- }
- }
- }
- }
-
- /**
- * Analyze the classpath for a split package
- *
- * @param pack
- * @param classpath
- * @param source
- * @return
- */
- private String diagnostic(String pack, List<Jar> classpath, File source) {
- // Default is like merge-first, but with a warning
- // Find the culprits
- pack = pack.replace('.', '/');
- List<Jar> culprits = new ArrayList<Jar>();
- for (Iterator<Jar> i = classpath.iterator(); i.hasNext();) {
- Jar culprit = (Jar) i.next();
- if (culprit.getDirectories().containsKey(pack)) {
- culprits.add(culprit);
- }
- }
- return "Split package "
- + pack
- + "\nUse directive -split-package:=(merge-first|merge-last|error|first) on Export/Private Package instruction to get rid of this warning\n"
- + "Package found in " + culprits + "\n"
- + "Reference from " + source + "\n" + "Classpath "
- + classpath;
- }
-
- private int getSplitStrategy(String type) {
- if (type == null)
- return SPLIT_DEFAULT;
-
- if (type.equals("merge-last"))
- return SPLIT_MERGE_LAST;
-
- if (type.equals("merge-first"))
- return SPLIT_MERGE_FIRST;
-
- if (type.equals("error"))
- return SPLIT_ERROR;
-
- if (type.equals("first"))
- return SPLIT_FIRST;
-
- error("Invalid strategy for split-package: " + type);
- return SPLIT_DEFAULT;
- }
-
- private Map<Instruction, Map<String, String>> replaceWitInstruction(
- Map<String, Map<String, String>> header, String type) {
- Map<Instruction, Map<String, String>> map = newMap();
- for (Iterator<Map.Entry<String, Map<String, String>>> e = header
- .entrySet().iterator(); e.hasNext();) {
- Map.Entry<String, Map<String, String>> entry = e.next();
- String pattern = entry.getKey();
- Instruction instr = Instruction.getPattern(pattern);
- String presence = entry.getValue().get(PRESENCE_DIRECTIVE);
- if ("optional".equals(presence))
- instr.setOptional();
- map.put(instr, entry.getValue());
- }
- return map;
- }
-
- private Instruction matches(
- Map<Instruction, Map<String, String>> instructions, String pack,
- Set<Instruction> superfluousPatterns) {
- for (Instruction pattern : instructions.keySet()) {
- if (pattern.matches(pack)) {
- superfluousPatterns.remove(pattern);
- return pattern;
- }
- }
- return null;
- }
-
- private Map<String, Map<String, String>> getHeader(String string) {
- if (string == null)
- return Collections.emptyMap();
- return parseHeader(getProperty(string));
- }
-
- /**
- * Parse the Bundle-Includes header. Files in the bundles Include header are
- * included in the jar. The source can be a directory or a file.
- *
- * @throws IOException
- * @throws FileNotFoundException
- */
- private void doIncludeResources(Jar jar) throws Exception {
- String includes = getProperty("Bundle-Includes");
- if (includes == null) {
- includes = getProperty(INCLUDERESOURCE);
- if ( includes == null )
- includes = getProperty("Include-Resource");
- }
- else
- warning("Please use -includeresource instead of Bundle-Includes");
-
- if (includes == null)
- return;
-
- Map<String, Map<String, String>> clauses = parseHeader(includes);
-
- for (Iterator<Map.Entry<String, Map<String, String>>> i = clauses
- .entrySet().iterator(); i.hasNext();) {
- Map.Entry<String, Map<String, String>> entry = i.next();
- doIncludeResource(jar, entry.getKey(), entry.getValue());
- }
- }
-
- private void doIncludeResource(Jar jar, String name,
- Map<String, String> extra) throws ZipException, IOException,
- Exception {
- boolean preprocess = false;
- if (name.startsWith("{") && name.endsWith("}")) {
- preprocess = true;
- name = name.substring(1, name.length() - 1).trim();
- }
-
- if (name.startsWith("@")) {
- extractFromJar(jar, name.substring(1));
- } else
- /*
- * NEW
- */
- if (extra.containsKey("literal")) {
- String literal = (String) extra.get("literal");
- Resource r = new EmbeddedResource(literal.getBytes("UTF-8"), 0);
- String x = (String) extra.get("extra");
- if (x != null)
- r.setExtra(x);
- jar.putResource(name, r);
- } else {
- String source;
- File sourceFile;
- String destinationPath;
-
- String parts[] = name.split("\\s*=\\s*");
- if (parts.length == 1) {
- // Just a copy, destination path defined by
- // source path.
- source = parts[0];
- sourceFile = getFile(source);
- // Directories should be copied to the root
- // but files to their file name ...
- if (sourceFile.isDirectory())
- destinationPath = "";
- else
- destinationPath = sourceFile.getName();
- } else {
- source = parts[1];
- sourceFile = getFile(source);
- destinationPath = parts[0];
- }
-
- // Some people insist on ending a directory with
- // a slash ... it now also works if you do /=dir
- if (destinationPath.endsWith("/"))
- destinationPath = destinationPath.substring(0, destinationPath
- .length() - 1);
-
- if (!sourceFile.exists()) {
- noSuchFile(jar, name, extra, source, destinationPath);
- } else
- copy(jar, destinationPath, sourceFile, preprocess, extra);
- }
- }
-
- private void noSuchFile(Jar jar, String clause, Map<String, String> extra,
- String source, String destinationPath) throws Exception {
- Jar src = getJarFromName(source, "Include-Resource " + source);
- if (src != null) {
- JarResource jarResource = new JarResource(src);
- jar.putResource(destinationPath, jarResource);
- } else {
- Resource lastChance = make.process(source);
- if (lastChance != null) {
- jar.putResource(destinationPath, lastChance);
- } else
- error("Input file does not exist: " + source);
- }
- }
-
- /**
- * Extra resources from a Jar and add them to the given jar. The clause is
- * the
- *
- * @param jar
- * @param clauses
- * @param i
- * @throws ZipException
- * @throws IOException
- */
- private void extractFromJar(Jar jar, String name) throws ZipException,
- IOException {
- // Inline all resources and classes from another jar
- // optionally appended with a modified regular expression
- // like @zip.jar!/META-INF/MANIFEST.MF
- int n = name.lastIndexOf("!/");
- Pattern filter = null;
- if (n > 0) {
- String fstring = name.substring(n + 2);
- name = name.substring(0, n);
- filter = wildcard(fstring);
- }
- Jar sub = getJarFromName(name, "extract from jar");
- if (sub == null)
- error("Can not find JAR file " + name);
- else
- jar.addAll(sub, filter);
- }
-
- private Pattern wildcard(String spec) {
- StringBuffer sb = new StringBuffer();
- for (int j = 0; j < spec.length(); j++) {
- char c = spec.charAt(j);
- switch (c) {
- case '.':
- sb.append("\\.");
- break;
-
- case '*':
- // test for ** (all directories)
- if (j < spec.length() - 1 && spec.charAt(j + 1) == '*') {
- sb.append(".*");
- j++;
- } else
- sb.append("[^/]*");
- break;
- default:
- sb.append(c);
- break;
- }
- }
- String s = sb.toString();
- try {
- return Pattern.compile(s);
- } catch (Exception e) {
- error("Invalid regular expression on wildcarding: " + spec
- + " used *");
- }
- return null;
- }
-
- private void copy(Jar jar, String path, File from, boolean preprocess,
- Map<String, String> extra) throws Exception {
- if (doNotCopy.matcher(from.getName()).matches())
- return;
-
- if (from.isDirectory()) {
- String next = path;
- if (next.length() != 0)
- next += '/';
-
- File files[] = from.listFiles();
- for (int i = 0; i < files.length; i++) {
- copy(jar, next + files[i].getName(), files[i], preprocess,
- extra);
- }
- } else {
- if (from.exists()) {
- Resource resource = new FileResource(from);
- if (preprocess) {
- resource = new PreprocessResource(this, resource);
- }
- jar.putResource(path, resource);
- } else {
- error("Input file does not exist: " + from);
- }
- }
- }
-
- private String getName(String where) {
- int n = where.lastIndexOf('/');
- if (n < 0)
- return where;
-
- return where.substring(n + 1);
- }
-
- public void setSourcepath(File[] files) {
- for (int i = 0; i < files.length; i++)
- addSourcepath(files[i]);
- }
-
- public void addSourcepath(File cp) {
- if (!cp.exists())
- warning("File on sourcepath that does not exist: " + cp);
-
- sourcePath.add(cp);
- }
-
- /**
- * Create a POM reseource for Maven containing as much information as
- * possible from the manifest.
- *
- * @param output
- * @param builder
- * @throws FileNotFoundException
- * @throws IOException
- */
- public void doPom(Jar dot) throws FileNotFoundException, IOException {
- {
- Manifest manifest = dot.getManifest();
- String name = manifest.getMainAttributes().getValue(
- Analyzer.BUNDLE_NAME);
- String description = manifest.getMainAttributes().getValue(
- Analyzer.BUNDLE_DESCRIPTION);
- String docUrl = manifest.getMainAttributes().getValue(
- Analyzer.BUNDLE_DOCURL);
- String version = manifest.getMainAttributes().getValue(
- Analyzer.BUNDLE_VERSION);
- String bundleVendor = manifest.getMainAttributes().getValue(
- Analyzer.BUNDLE_VENDOR);
- ByteArrayOutputStream s = new ByteArrayOutputStream();
- PrintStream ps = new PrintStream(s);
- String bsn = manifest.getMainAttributes().getValue(
- Analyzer.BUNDLE_SYMBOLICNAME);
- String licenses = manifest.getMainAttributes().getValue(
- BUNDLE_LICENSE);
-
- if (bsn == null) {
- error("Can not create POM unless Bundle-SymbolicName is set");
- return;
- }
-
- bsn = bsn.trim();
- int n = bsn.lastIndexOf('.');
- if (n <= 0) {
- error("Can not create POM unless Bundle-SymbolicName contains a .");
- ps.close();
- s.close();
- return;
- }
- String groupId = bsn.substring(0, n);
- String artifactId = bsn.substring(n + 1);
- ps
- .println("<project xmlns='http://maven.apache.org/POM/4.0.0' xmlns:xsi='http://www.w3.org/2001/XMLSchema-instance' xsi:schemaLocation='http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd'>");
- ps.println(" <modelVersion>4.0.0</modelVersion>");
- ps.println(" <groupId>" + groupId + "</groupId>");
-
- n = artifactId.indexOf(';');
- if (n > 0)
- artifactId = artifactId.substring(0, n).trim();
-
- ps.println(" <artifactId>" + artifactId + "</artifactId>");
- ps.println(" <version>" + version + "</version>");
- if (description != null) {
- ps.println(" <description>");
- ps.print(" ");
- ps.println(description);
- ps.println(" </description>");
- }
- if (name != null) {
- ps.print(" <name>");
- ps.print(name);
- ps.println("</name>");
- }
- if (docUrl != null) {
- ps.print(" <url>");
- ps.print(docUrl);
- ps.println("</url>");
- }
-
- if (bundleVendor != null) {
- Matcher m = NAME_URL.matcher(bundleVendor);
- String namePart = bundleVendor;
- String urlPart = null;
- if (m.matches()) {
- namePart = m.group(1);
- urlPart = m.group(2);
- }
- ps.println(" <organization>");
- ps.print(" <name>");
- ps.print(namePart.trim());
- ps.println("</name>");
- if (urlPart != null) {
- ps.print(" <url>");
- ps.print(urlPart.trim());
- ps.println("</url>");
- }
- ps.println(" </organization>");
- }
- if (licenses != null) {
- ps.println(" <licenses>");
- Map<String, Map<String, String>> map = parseHeader(licenses);
- for (Iterator<Map.Entry<String, Map<String, String>>> e = map
- .entrySet().iterator(); e.hasNext();) {
- Map.Entry<String, Map<String, String>> entry = e.next();
- ps.println(" <license>");
- Map<String, String> values = entry.getValue();
- print(ps, values, "name", "name", (String) values
- .get("url"));
- print(ps, values, "url", "url", null);
- print(ps, values, "distribution", "distribution", "repo");
- ps.println(" </license>");
- }
- ps.println(" </licenses>");
- }
- ps.println("</project>");
- ps.close();
- s.close();
- dot
- .putResource("pom.xml", new EmbeddedResource(s
- .toByteArray(), 0));
- }
- }
-
- /**
- * Utility function to print a tag from a map
- *
- * @param ps
- * @param values
- * @param string
- * @param tag
- * @param object
- */
- private void print(PrintStream ps, Map<String, String> values,
- String string, String tag, String object) {
- String value = (String) values.get(string);
- if (value == null)
- value = object;
- if (value == null)
- return;
- ps.println(" <" + tag + ">" + value.trim() + "</" + tag + ">");
- }
-
- public void close() {
- super.close();
- }
-
- /**
- * Build Multiple jars. If the -sub command is set, we filter the file with
- * the given patterns.
- *
- * @return
- * @throws Exception
- */
- public Jar[] builds() throws Exception {
- begin();
-
- // Are we acting as a conduit for another JAR?
- String conduit = getProperty(CONDUIT);
- if (conduit != null) {
- Map<String, Map<String, String>> map = parseHeader(conduit);
- Jar[] result = new Jar[map.size()];
- int n = 0;
- for (String file : map.keySet()) {
- Jar c = new Jar(getFile(file));
- addClose(c);
- String name = map.get(file).get("name");
- if (name != null)
- c.setName(name);
-
- result[n++] = c;
- }
- return result;
- }
-
- // If no -sub property, then reuse this builder object
- // other wise, build all the sub parts.
- String sub = getProperty(SUB);
- if (sub == null) {
- Jar jar = build();
- if (jar == null)
- return new Jar[0];
-
- return new Jar[] { jar };
- }
-
- List<Jar> result = new ArrayList<Jar>();
-
- // Get the Instruction objects that match the sub header
- Set<Instruction> subs = replaceWitInstruction(parseHeader(sub), SUB)
- .keySet();
-
- // Get the member files of this directory
- List<File> members = new ArrayList<File>(Arrays.asList(getBase()
- .listFiles()));
-
- getProperties().remove(SUB);
- // For each member file
- nextFile: while (members.size() > 0) {
-
- File file = members.remove(0);
- if (file.equals(getPropertiesFile()))
- continue nextFile;
-
- for (Iterator<Instruction> i = subs.iterator(); i.hasNext();) {
-
- Instruction instruction = i.next();
- if (instruction.matches(file.getName())) {
-
- if (!instruction.isNegated()) {
-
- Builder builder = null;
- try {
- builder = getSubBuilder();
- addClose(builder);
- builder.setProperties(file);
- builder.setProperty(SUB, "");
- // Recursively build
- // TODO
- Jar jar = builder.build();
- jar.setName(builder.getBsn());
- result.add(jar);
- } catch (Exception e) {
- e.printStackTrace();
- error("Sub Building " + file, e);
- }
- if (builder != null)
- getInfo(builder, file.getName() + ": ");
- }
-
- // Because we matched (even though we could be negated)
- // we skip any remaining searches
- continue nextFile;
- }
- }
- }
- setProperty(SUB, sub);
- return result.toArray(new Jar[result.size()]);
- }
-
- protected Builder getSubBuilder() throws Exception {
- return new Builder(this);
- }
-
- /**
- * A macro to convert a maven version to an OSGi version
- */
-
- public String _maven_version(String args[]) {
- if (args.length > 2)
- error("${maven_version} macro receives too many arguments "
- + Arrays.toString(args));
- else if (args.length < 2)
- error("${maven_version} macro has no arguments, use ${maven_version;1.2.3-SNAPSHOT}");
- else {
- return cleanupVersion(args[1]);
- }
- return null;
- }
-
- public String _permissions(String args[]) throws IOException {
- StringBuilder sb = new StringBuilder();
-
- for (String arg : args) {
- if ("packages".equals(arg) || "all".equals(arg)) {
- for (String imp : getImports().keySet()) {
- if (!imp.startsWith("java.")) {
- sb.append("(org.osgi.framework.PackagePermission \"");
- sb.append(imp);
- sb.append("\" \"import\")\r\n");
- }
- }
- for (String exp : getExports().keySet()) {
- sb.append("(org.osgi.framework.PackagePermission \"");
- sb.append(exp);
- sb.append("\" \"export\")\r\n");
- }
- } else if ("admin".equals(arg) || "all".equals(arg)) {
- sb.append("(org.osgi.framework.AdminPermission)");
- } else if ("permissions".equals(arg))
- ;
- else
- error("Invalid option in ${permissions}: %s", arg);
- }
- return sb.toString();
- }
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java b/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java
deleted file mode 100644
index e09e00f..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/ClassDataCollector.java
+++ /dev/null
@@ -1,11 +0,0 @@
-package aQute.lib.osgi;
-
-public interface ClassDataCollector {
- void classBegin(int access, String name);
- void extendsClass(String name);
- void implementsInterfaces(String name[]);
- void field(int access, String descriptor);
- void method(int access, String descriptor);
- void addReference(String token);
- void classEnd();
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java b/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java
deleted file mode 100644
index ce709df..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Clazz.java
+++ /dev/null
@@ -1,812 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.nio.*;
-import java.util.*;
-
-public class Clazz {
- public static enum QUERY {
- IMPLEMENTS, EXTENDS, IMPORTS, NAMED, ANY, VERSION
- };
-
- static protected class Assoc {
- Assoc(byte tag, int a, int b) {
- this.tag = tag;
- this.a = a;
- this.b = b;
- }
-
- byte tag;
- int a;
- int b;
- }
-
- final static byte SkipTable[] = { 0, // 0 non existent
- -1, // 1 CONSTANT_utf8 UTF 8, handled in
- // method
- -1, // 2
- 4, // 3 CONSTANT_Integer
- 4, // 4 CONSTANT_Float
- 8, // 5 CONSTANT_Long (index +=2!)
- 8, // 6 CONSTANT_Double (index +=2!)
- -1, // 7 CONSTANT_Class
- 2, // 8 CONSTANT_String
- 4, // 9 CONSTANT_FieldRef
- 4, // 10 CONSTANT_MethodRef
- 4, // 11 CONSTANT_InterfaceMethodRef
- 4, // 12 CONSTANT_NameAndType
- };
-
- String className;
- Object pool[];
- int intPool[];
- Map<String, Map<String, String>> imports = new HashMap<String, Map<String, String>>();
- String path;
-
- // static String type = "([BCDFIJSZ\\[]|L[^<>]+;)";
- // static Pattern descriptor = Pattern.compile("\\(" + type + "*\\)(("
- // + type + ")|V)");
- int minor = 0;
- int major = 0;
-
- String sourceFile;
- Set<String> xref;
- Set<Integer> classes;
- Set<Integer> descriptors;
- int forName = 0;
- int class$ = 0;
- String[] interfaces;
- String zuper;
- ClassDataCollector cd = new ClassDataCollector() {
- public void addReference(
- String token) {
- }
-
- public void classBegin(
- int access,
- String name) {
- }
-
- public void classEnd() {
- }
-
- public void extendsClass(
- String name) {
- }
-
- public void field(
- int access,
- String descriptor) {
- }
-
- public void implementsInterfaces(
- String[] name) {
- }
-
- public void method(
- int access,
- String descriptor) {
- }
- };
-
- public Clazz(String path) {
- this.path = path;
- }
-
- public Clazz(String path, InputStream in) throws IOException {
- this.path = path;
- DataInputStream din = new DataInputStream(in);
- parseClassFile(din);
- din.close();
- }
-
- Set<String> parseClassFile(DataInputStream in) throws IOException {
-
- xref = new HashSet<String>();
- classes = new HashSet<Integer>();
- descriptors = new HashSet<Integer>();
-
- boolean crawl = false; // Crawl the byte code
- int magic = in.readInt();
- if (magic != 0xCAFEBABE)
- throw new IOException("Not a valid class file (no CAFEBABE header)");
-
- minor = in.readUnsignedShort(); // minor version
- major = in.readUnsignedShort(); // major version
- int count = in.readUnsignedShort();
- pool = new Object[count];
- intPool = new int[count];
-
- process: for (int poolIndex = 1; poolIndex < count; poolIndex++) {
- byte tag = in.readByte();
- switch (tag) {
- case 0:
- break process;
- case 1:
- constantUtf8(in, poolIndex);
- break;
-
- // For some insane optimization reason are
- // the long and the double two entries in the
- // constant pool. See 4.4.5
- case 5:
- constantLong(in, poolIndex);
- poolIndex++;
- break;
-
- case 6:
- constantDouble(in, poolIndex);
- poolIndex++;
- break;
-
- case 7:
- constantClass(in, poolIndex);
- break;
-
- case 8:
- constantString(in, poolIndex);
- break;
-
- case 10: // Method ref
- methodRef(in, poolIndex);
- break;
-
- // Name and Type
- case 12:
- nameAndType(in, poolIndex, tag);
- break;
-
- // We get the skip count for each record type
- // from the SkipTable. This will also automatically
- // abort when
- default:
- if (tag == 2)
- throw new IOException("Invalid tag " + tag);
- in.skipBytes(SkipTable[tag]);
- break;
- }
- }
-
- pool(pool, intPool);
- /*
- * Parse after the constant pool, code thanks to Hans Christian
- * Falkenberg
- */
-
- int access_flags = in.readUnsignedShort(); // access
- int this_class = in.readUnsignedShort();
- className = (String) pool[intPool[this_class]];
- cd.classBegin(access_flags, className);
-
- try {
-
- int super_class = in.readUnsignedShort();
- zuper = (String) pool[intPool[super_class]];
- if (zuper != null) {
- addReference(zuper);
- cd.extendsClass(zuper);
- }
-
- int interfacesCount = in.readUnsignedShort();
- if (interfacesCount > 0) {
- interfaces = new String[interfacesCount];
- for (int i = 0; i < interfacesCount; i++)
- interfaces[i] = (String) pool[intPool[in
- .readUnsignedShort()]];
- cd.implementsInterfaces(interfaces);
- }
-
- int fieldsCount = in.readUnsignedShort();
- for (int i = 0; i < fieldsCount; i++) {
- access_flags = in.readUnsignedShort(); // skip access flags
- int name_index = in.readUnsignedShort();
- int descriptor_index = in.readUnsignedShort();
-
- // Java prior to 1.5 used a weird
- // static variable to hold the com.X.class
- // result construct. If it did not find it
- // it would create a variable class$com$X
- // that would be used to hold the class
- // object gotten with Class.forName ...
- // Stupidly, they did not actively use the
- // class name for the field type, so bnd
- // would not see a reference. We detect
- // this case and add an artificial descriptor
- String name = pool[name_index].toString(); // name_index
- if (name.startsWith("class$")) {
- crawl = true;
- }
- cd.field(access_flags, pool[descriptor_index].toString());
- descriptors.add(new Integer(descriptor_index));
- doAttributes(in, false);
- }
-
- //
- // Check if we have to crawl the code to find
- // the ldc(_w) <string constant> invokestatic Class.forName
- // if so, calculate the method ref index so we
- // can do this efficiently
- //
- if (crawl) {
- forName = findMethod("java/lang/Class", "forName",
- "(Ljava/lang/String;)Ljava/lang/Class;");
- class$ = findMethod(className, "class$",
- "(Ljava/lang/String;)Ljava/lang/Class;");
- }
-
- //
- // Handle the methods
- //
- int methodCount = in.readUnsignedShort();
- for (int i = 0; i < methodCount; i++) {
- access_flags = in.readUnsignedShort();
- /* int name_index = */in.readUnsignedShort();
- int descriptor_index = in.readUnsignedShort();
- // String s = (String) pool[name_index];
- descriptors.add(new Integer(descriptor_index));
- cd.method(access_flags, pool[descriptor_index].toString());
- doAttributes(in, crawl);
- }
-
- doAttributes(in, false);
-
- //
- // Now iterate over all classes we found and
- // parse those as well. We skip duplicates
- //
-
- for (Iterator<Integer> e = classes.iterator(); e.hasNext();) {
- int class_index = e.next().shortValue();
- doClassReference((String) pool[class_index]);
- }
-
- //
- // Parse all the descriptors we found
- //
-
- for (Iterator<Integer> e = descriptors.iterator(); e.hasNext();) {
- Integer index = e.next();
- String prototype = (String) pool[index.intValue()];
- if (prototype != null)
- parseDescriptor(prototype);
- else
- System.err.println("Unrecognized descriptor: " + index);
- }
- Set<String> xref = this.xref;
- reset();
- return xref;
- } finally {
- cd.classEnd();
- }
- }
-
- protected void pool(Object[] pool, int[] intPool) {
- }
-
- /**
- * @param in
- * @param poolIndex
- * @param tag
- * @throws IOException
- */
- protected void nameAndType(DataInputStream in, int poolIndex, byte tag)
- throws IOException {
- int name_index = in.readUnsignedShort();
- int descriptor_index = in.readUnsignedShort();
- descriptors.add(new Integer(descriptor_index));
- pool[poolIndex] = new Assoc(tag, name_index, descriptor_index);
- }
-
- /**
- * @param in
- * @param poolIndex
- * @param tag
- * @throws IOException
- */
- private void methodRef(DataInputStream in, int poolIndex)
- throws IOException {
- int class_index = in.readUnsignedShort();
- int name_and_type_index = in.readUnsignedShort();
- pool[poolIndex] = new Assoc((byte) 10, class_index, name_and_type_index);
- }
-
- /**
- * @param in
- * @param poolIndex
- * @throws IOException
- */
- private void constantString(DataInputStream in, int poolIndex)
- throws IOException {
- int string_index = in.readUnsignedShort();
- intPool[poolIndex] = string_index;
- }
-
- /**
- * @param in
- * @param poolIndex
- * @throws IOException
- */
- protected void constantClass(DataInputStream in, int poolIndex)
- throws IOException {
- int class_index = in.readUnsignedShort();
- classes.add(new Integer(class_index));
- intPool[poolIndex] = class_index;
- }
-
- /**
- * @param in
- * @throws IOException
- */
- protected void constantDouble(DataInputStream in, int poolIndex)
- throws IOException {
- in.skipBytes(8);
- }
-
- /**
- * @param in
- * @throws IOException
- */
- protected void constantLong(DataInputStream in, int poolIndex)
- throws IOException {
- in.skipBytes(8);
- }
-
- /**
- * @param in
- * @param poolIndex
- * @throws IOException
- */
- protected void constantUtf8(DataInputStream in, int poolIndex)
- throws IOException {
- // CONSTANT_Utf8
-
- String name = in.readUTF();
- xref.add(name);
- pool[poolIndex] = name;
- }
-
- /**
- * Find a method reference in the pool that points to the given class,
- * methodname and descriptor.
- *
- * @param clazz
- * @param methodname
- * @param descriptor
- * @return index in constant pool
- */
- private int findMethod(String clazz, String methodname, String descriptor) {
- for (int i = 1; i < pool.length; i++) {
- if (pool[i] instanceof Assoc) {
- Assoc methodref = (Assoc) pool[i];
- if (methodref.tag == 10) {
- // Method ref
- int class_index = methodref.a;
- int class_name_index = intPool[class_index];
- if (clazz.equals(pool[class_name_index])) {
- int name_and_type_index = methodref.b;
- Assoc name_and_type = (Assoc) pool[name_and_type_index];
- if (name_and_type.tag == 12) {
- // Name and Type
- int name_index = name_and_type.a;
- int type_index = name_and_type.b;
- if (methodname.equals(pool[name_index])) {
- if (descriptor.equals(pool[type_index])) {
- return i;
- }
- }
- }
- }
- }
- }
- }
- return -1;
- }
-
- private void doClassReference(String next) {
- if (next != null) {
- String normalized = normalize(next);
- if (normalized != null) {
- cd.addReference(next);
- String pack = getPackage(normalized);
- packageReference(pack);
- }
- } else
- throw new IllegalArgumentException("Invalid class, parent=");
- }
-
- /**
- * Called for each attribute in the class, field, or method.
- *
- * @param in
- * The stream
- * @throws IOException
- */
- private void doAttributes(DataInputStream in, boolean crawl)
- throws IOException {
- int attributesCount = in.readUnsignedShort();
- for (int j = 0; j < attributesCount; j++) {
- // skip name CONSTANT_Utf8 pointer
- doAttribute(in, crawl);
- }
- }
-
- /**
- * Process a single attribute, if not recognized, skip it.
- *
- * @param in
- * the data stream
- * @throws IOException
- */
- private void doAttribute(DataInputStream in, boolean crawl)
- throws IOException {
- int attribute_name_index = in.readUnsignedShort();
- String attributeName = (String) pool[attribute_name_index];
- if (attribute_name_index == 560)
- System.out.println("Index " + attribute_name_index + ":"
- + attributeName);
- long attribute_length = in.readInt();
- attribute_length &= 0xFFFFFFFF;
- if ("RuntimeVisibleAnnotations".equals(attributeName))
- doAnnotations(in);
- else if ("RuntimeVisibleParameterAnnotations".equals(attributeName))
- doParameterAnnotations(in);
- else if ("SourceFile".equals(attributeName))
- doSourceFile(in);
- else if ("Code".equals(attributeName) && crawl)
- doCode(in);
- else {
- if (attribute_length > 0x7FFFFFFF) {
- throw new IllegalArgumentException("Attribute > 2Gb");
- }
- in.skipBytes((int) attribute_length);
- }
- }
-
- /**
- * <pre>
- * Code_attribute {
- * u2 attribute_name_index;
- * u4 attribute_length;
- * u2 max_stack;
- * u2 max_locals;
- * u4 code_length;
- * u1 code[code_length];
- * u2 exception_table_length;
- * { u2 start_pc;
- * u2 end_pc;
- * u2 handler_pc;
- * u2 catch_type;
- * } exception_table[exception_table_length];
- * u2 attributes_count;
- * attribute_info attributes[attributes_count];
- * }
- * </pre>
- *
- * @param in
- * @param pool
- * @throws IOException
- */
- private void doCode(DataInputStream in) throws IOException {
- /* int max_stack = */in.readUnsignedShort();
- /* int max_locals = */in.readUnsignedShort();
- int code_length = in.readInt();
- byte code[] = new byte[code_length];
- in.readFully(code);
- crawl(code);
- int exception_table_length = in.readUnsignedShort();
- in.skipBytes(exception_table_length * 8);
- doAttributes(in, false);
- }
-
- /**
- * We must find Class.forName references ...
- *
- * @param code
- */
- protected void crawl(byte[] code) {
- ByteBuffer bb = ByteBuffer.wrap(code);
- bb.order(ByteOrder.BIG_ENDIAN);
- int lastReference = -1;
-
- while (bb.remaining() > 0) {
- int instruction = 0xFF & bb.get();
- switch (instruction) {
- case OpCodes.ldc:
- lastReference = 0xFF & bb.get();
- break;
-
- case OpCodes.ldc_w:
- lastReference = 0xFFFF & bb.getShort();
- break;
-
- case OpCodes.invokestatic:
- int methodref = 0xFFFF & bb.getShort();
- if ((methodref == forName || methodref == class$)
- && lastReference != -1
- && pool[intPool[lastReference]] instanceof String) {
- String clazz = (String) pool[intPool[lastReference]];
- doClassReference(clazz.replace('.', '/'));
- }
- break;
-
- case OpCodes.tableswitch:
- // Skip to place divisible by 4
- while ((bb.position() & 0x3) != 0)
- bb.get();
- /* int deflt = */
- bb.getInt();
- int low = bb.getInt();
- int high = bb.getInt();
- bb.position(bb.position() + (high - low + 1) * 4);
- lastReference = -1;
- break;
-
- case OpCodes.lookupswitch:
- // Skip to place divisible by 4
- while ((bb.position() & 0x3) != 0)
- bb.get();
- /* deflt = */
- bb.getInt();
- int npairs = bb.getInt();
- bb.position(bb.position() + npairs * 8);
- lastReference = -1;
- break;
-
- default:
- lastReference = -1;
- bb.position(bb.position() + OpCodes.OFFSETS[instruction]);
- }
- }
- }
-
- private void doSourceFile(DataInputStream in) throws IOException {
- int sourcefile_index = in.readUnsignedShort();
- this.sourceFile = pool[sourcefile_index].toString();
- }
-
- private void doParameterAnnotations(DataInputStream in) throws IOException {
- int num_parameters = in.readUnsignedByte();
- for (int p = 0; p < num_parameters; p++) {
- int num_annotations = in.readUnsignedShort(); // # of annotations
- for (int a = 0; a < num_annotations; a++) {
- doAnnotation(in);
- }
- }
- }
-
- private void doAnnotations(DataInputStream in) throws IOException {
- int num_annotations = in.readUnsignedShort(); // # of annotations
- for (int a = 0; a < num_annotations; a++) {
- doAnnotation(in);
- }
- }
-
- private void doAnnotation(DataInputStream in) throws IOException {
- int type_index = in.readUnsignedShort();
- descriptors.add(new Integer(type_index));
- int num_element_value_pairs = in.readUnsignedShort();
- for (int v = 0; v < num_element_value_pairs; v++) {
- /* int element_name_index = */in.readUnsignedShort();
- doElementValue(in);
- }
- }
-
- private void doElementValue(DataInputStream in) throws IOException {
- int tag = in.readUnsignedByte();
- switch (tag) {
- case 'B':
- case 'C':
- case 'D':
- case 'F':
- case 'I':
- case 'J':
- case 'S':
- case 'Z':
- case 's':
- /* int const_value_index = */
- in.readUnsignedShort();
- break;
-
- case 'e':
- int type_name_index = in.readUnsignedShort();
- descriptors.add(new Integer(type_name_index));
- /* int const_name_index = */
- in.readUnsignedShort();
- break;
-
- case 'c':
- int class_info_index = in.readUnsignedShort();
- descriptors.add(new Integer(class_info_index));
- break;
-
- case '@':
- doAnnotation(in);
- break;
-
- case '[':
- int num_values = in.readUnsignedShort();
- for (int i = 0; i < num_values; i++) {
- doElementValue(in);
- }
- break;
-
- default:
- throw new IllegalArgumentException(
- "Invalid value for Annotation ElementValue tag " + tag);
- }
- }
-
- void packageReference(String pack) {
- if (pack.indexOf('<') >= 0)
- System.out.println("Oops: " + pack);
- if (!imports.containsKey(pack))
- imports.put(pack, new LinkedHashMap<String, String>());
- }
-
- public void parseDescriptor(String prototype) {
- if (prototype.startsWith("("))
- parseMethodDescriptor(prototype);
- else
- addReference(prototype);
- }
-
- void parseMethodDescriptor(String prototype) {
- int last = prototype.indexOf(')');
- if (last < 0)
- throw new IllegalArgumentException(
- "Invalid method descriptor in class file: " + className
- + " " + prototype);
-
- for (int i = 1; i < last; i++) {
- if (prototype.charAt(i) == 'L') {
- int next = prototype.indexOf(';', i);
- addReference(prototype.substring(i, next));
- i = next;
- }
- }
- addReference(prototype.substring(last + 1));
- }
-
- private void addReference(String token) {
- cd.addReference(token);
- while (token.startsWith("["))
- token = token.substring(1);
-
- if (token.startsWith("L")) {
- String clazz = normalize(token.substring(1));
- if (clazz.startsWith("java/"))
- return;
- String pack = getPackage(clazz);
- packageReference(pack);
- }
- }
-
- static String normalize(String s) {
- if (s.startsWith("[L"))
- return normalize(s.substring(2));
- if (s.startsWith("["))
- if (s.length() == 2)
- return null;
- else
- return normalize(s.substring(1));
- if (s.endsWith(";"))
- return normalize(s.substring(0, s.length() - 1));
- return s + ".class";
- }
-
- public static String getPackage(String clazz) {
- int n = clazz.lastIndexOf('/');
- if (n < 0)
- return ".";
- return clazz.substring(0, n).replace('/', '.');
- }
-
- public Map<String, Map<String, String>> getReferred() {
- return imports;
- }
-
- String getClassName() {
- return className;
- }
-
- public String getPath() {
- return path;
- }
-
- public Set<String> xref(InputStream in) throws IOException {
- DataInputStream din = new DataInputStream(in);
- Set<String> set = parseClassFile(din);
- din.close();
- return set;
- }
-
- public String getSourceFile() {
- return sourceFile;
- }
-
- /**
- * .class construct for different compilers
- *
- * sun 1.1 Detect static variable class$com$acme$MyClass 1.2 " 1.3 " 1.4 "
- * 1.5 ldc_w (class) 1.6 "
- *
- * eclipse 1.1 class$0, ldc (string), invokestatic Class.forName 1.2 " 1.3 "
- * 1.5 ldc (class) 1.6 "
- *
- * 1.5 and later is not an issue, sun pre 1.5 is easy to detect the static
- * variable that decodes the class name. For eclipse, the class$0 gives away
- * we have a reference encoded in a string.
- * compilerversions/compilerversions.jar contains test versions of all
- * versions/compilers.
- */
-
- public void reset() {
- pool = null;
- intPool = null;
- xref = null;
- classes = null;
- descriptors = null;
- }
-
- public boolean is(QUERY query, Instruction instr,
- Map<String, Clazz> classspace) {
- switch (query) {
- case ANY:
- return true;
-
- case NAMED:
- if (instr.matches(getClassName()))
- return !instr.isNegated();
- return false;
-
- case VERSION:
- String v = major + "/" + minor;
- if (instr.matches(v))
- return !instr.isNegated();
- return false;
-
- case IMPLEMENTS:
- for (int i = 0; interfaces != null && i < interfaces.length; i++) {
- if (instr.matches(interfaces[i]))
- return !instr.isNegated();
- }
- break;
- case EXTENDS:
- if (zuper == null)
- return false;
-
- if (instr.matches(zuper))
- return !instr.isNegated();
- break;
-
- case IMPORTS:
- for (String imp : imports.keySet()) {
- if (instr.matches(imp.replace('.', '/')))
- return !instr.isNegated();
- }
- }
-
- if (zuper == null || classspace == null)
- return false;
-
- Clazz clazz = classspace.get(zuper);
- if (clazz == null)
- return false;
-
- return clazz.is(query, instr, classspace);
- }
-
- public String toString() {
- return getFQN();
- }
-
- public String getFQN() {
- return getClassName().replace('/', '.');
- }
-
- public void setClassDataCollector(ClassDataCollector cd) {
- this.cd = cd;
- }
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java b/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java
deleted file mode 100644
index 9535bac..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Constants.java
+++ /dev/null
@@ -1,160 +0,0 @@
-package aQute.lib.osgi;
-
-import java.util.*;
-import java.util.regex.*;
-
-public interface Constants {
- String BUNDLE_CLASSPATH = "Bundle-ClassPath";
- String BUNDLE_COPYRIGHT = "Bundle-Copyright";
- String BUNDLE_DESCRIPTION = "Bundle-Description";
- String BUNDLE_NAME = "Bundle-Name";
- String BUNDLE_NATIVECODE = "Bundle-NativeCode";
- String EXPORT_PACKAGE = "Export-Package";
- String EXPORT_SERVICE = "Export-Service";
- String IMPORT_PACKAGE = "Import-Package";
- String DYNAMICIMPORT_PACKAGE = "DynamicImport-Package";
- String IMPORT_SERVICE = "Import-Service";
- String BUNDLE_VENDOR = "Bundle-Vendor";
- String BUNDLE_VERSION = "Bundle-Version";
- String BUNDLE_DOCURL = "Bundle-DocURL";
- String BUNDLE_CONTACTADDRESS = "Bundle-ContactAddress";
- String BUNDLE_ACTIVATOR = "Bundle-Activator";
- String BUNDLE_REQUIREDEXECUTIONENVIRONMENT = "Bundle-RequiredExecutionEnvironment";
- String BUNDLE_SYMBOLICNAME = "Bundle-SymbolicName";
- String BUNDLE_LOCALIZATION = "Bundle-Localization";
- String REQUIRE_BUNDLE = "Require-Bundle";
- String FRAGMENT_HOST = "Fragment-Host";
- String BUNDLE_MANIFESTVERSION = "Bundle-ManifestVersion";
- String SERVICE_COMPONENT = "Service-Component";
- String BUNDLE_LICENSE = "Bundle-License";
- String PRIVATE_PACKAGE = "Private-Package";
- String IGNORE_PACKAGE = "Ignore-Package";
- String INCLUDE_RESOURCE = "Include-Resource";
- String CONDITIONAL_PACKAGE = "Conditional-Package";
- String BND_LASTMODIFIED = "Bnd-LastModified";
- String CREATED_BY = "Created-By";
- String TOOL = "Tool";
-
- String headers[] = {
- BUNDLE_ACTIVATOR, BUNDLE_CONTACTADDRESS, BUNDLE_COPYRIGHT,
- BUNDLE_DESCRIPTION, BUNDLE_DOCURL, BUNDLE_LOCALIZATION,
- BUNDLE_NATIVECODE, BUNDLE_VENDOR, BUNDLE_VERSION, BUNDLE_LICENSE,
- BUNDLE_CLASSPATH, SERVICE_COMPONENT, EXPORT_PACKAGE,
- IMPORT_PACKAGE, BUNDLE_LOCALIZATION, BUNDLE_MANIFESTVERSION,
- BUNDLE_NAME, BUNDLE_NATIVECODE,
- BUNDLE_REQUIREDEXECUTIONENVIRONMENT, BUNDLE_SYMBOLICNAME,
- BUNDLE_VERSION, FRAGMENT_HOST, PRIVATE_PACKAGE, IGNORE_PACKAGE,
- INCLUDE_RESOURCE, REQUIRE_BUNDLE, IMPORT_SERVICE, EXPORT_SERVICE,
- CONDITIONAL_PACKAGE, BND_LASTMODIFIED };
-
- String BUILDPATH = "-buildpath";
- String BUMPPOLICY = "-bumppolicy";
- String CONDUIT = "-conduit";
- String CLASSPATH = "-classpath";
- String DEPENDSON = "-dependson";
- String DONOTCOPY = "-donotcopy";
- String EXPORT_CONTENTS = "-exportcontents";
- String FAIL_OK = "-failok";
- String INCLUDE = "-include";
- String INCLUDERESOURCE = "-includeresource";
- String MAKE = "-make";
- String MANIFEST = "-manifest";
- String NOEXTRAHEADERS = "-noextraheaders";
- String NOUSES = "-nouses";
- String NOPE = "-nope";
- String PEDANTIC = "-pedantic";
- String PLUGIN = "-plugin";
- String POM = "-pom";
- String REMOVE_HEADERS = "-removeheaders";
- String RESOURCEONLY = "-resourceonly";
- String SOURCES = "-sources";
- String SOURCEPATH = "-sourcepath";
- String SUB = "-sub";
- String RUNPROPERTIES = "-runproperties";
- String RUNSYSTEMPACKAGES = "-runsystempackages";
- String RUNBUNDLES = "-runbundles";
- String RUNPATH = "-runpath";
- String RUNVM = "-runvm";
-
- String REPORTNEWER = "-reportnewer";
- String SIGN = "-sign";
- String TESTPACKAGES = "-testpackages";
- String TESTREPORT = "-testreport";
- String UNDERTEST = "-undertest";
- String VERBOSE = "-verbose";
- String VERSIONPOLICY = "-versionpolicy";
-
- String options[] = { BUILDPATH,
- BUMPPOLICY, CONDUIT, CLASSPATH, DEPENDSON, DONOTCOPY,
- EXPORT_CONTENTS, FAIL_OK, INCLUDE, INCLUDERESOURCE, MAKE, MANIFEST, NOEXTRAHEADERS,
- NOUSES, NOPE, PEDANTIC, PLUGIN, POM, REMOVE_HEADERS, RESOURCEONLY,
- SOURCES, SOURCEPATH, SOURCES, SOURCEPATH, SUB, RUNBUNDLES, RUNPATH,
- RUNSYSTEMPACKAGES, RUNPROPERTIES, REPORTNEWER, UNDERTEST,
- TESTPACKAGES, TESTREPORT, VERBOSE };
-
- char DUPLICATE_MARKER = '~';
-
- String SPLIT_PACKAGE_DIRECTIVE = "-split-package:";
- String IMPORT_DIRECTIVE = "-import:";
- String NO_IMPORT_DIRECTIVE = "-noimport:";
- String REMOVE_ATTRIBUTE_DIRECTIVE = "-remove-attribute:";
- String USES_DIRECTIVE = "uses:";
- String PRESENCE_DIRECTIVE = "presence:";
-
- String KEYSTORE_LOCATION_DIRECTIVE = "keystore:";
- String KEYSTORE_PROVIDER_DIRECTIVE = "provider:";
- String KEYSTORE_PASSWORD_DIRECTIVE = "password:";
- String SIGN_PASSWORD_DIRECTIVE = "sign-password:";
-
- String directives[] = {
- SPLIT_PACKAGE_DIRECTIVE, NO_IMPORT_DIRECTIVE, IMPORT_DIRECTIVE,
- "resolution:", "include:", "uses:", "exclude:", USES_DIRECTIVE,
- KEYSTORE_LOCATION_DIRECTIVE, KEYSTORE_PROVIDER_DIRECTIVE,
- KEYSTORE_PASSWORD_DIRECTIVE, SIGN_PASSWORD_DIRECTIVE,
-
- // TODO
- };
-
- String USES_USES = "<<USES>>";
- String CURRENT_USES = "@uses";
- String IMPORT_REFERENCE = "reference";
- String IMPORT_PRIVATE = "private";
- String[] importDirectives = {
- IMPORT_REFERENCE, IMPORT_PRIVATE };
-
- String COMPONENT_FACTORY = "factory:";
- String COMPONENT_SERVICEFACTORY = "servicefactory:";
- String COMPONENT_IMMEDIATE = "immediate:";
- String COMPONENT_ENABLED = "enabled:";
- String COMPONENT_DYNAMIC = "dynamic:";
- String COMPONENT_MULTIPLE = "multiple:";
- String COMPONENT_PROVIDE = "provide:";
- String COMPONENT_OPTIONAL = "optional:";
- String COMPONENT_PROPERTIES = "properties:";
- String COMPONENT_IMPLEMENTATION = "implementation:";
- String[] componentDirectives = new String[] {
- COMPONENT_FACTORY, COMPONENT_IMMEDIATE, COMPONENT_ENABLED,
- COMPONENT_DYNAMIC, COMPONENT_MULTIPLE, COMPONENT_PROVIDE,
- COMPONENT_OPTIONAL, COMPONENT_PROPERTIES, COMPONENT_IMPLEMENTATION,
- COMPONENT_SERVICEFACTORY };
-
- // static Map EES = new HashMap();
- static Set<String> SET_COMPONENT_DIRECTIVES = new HashSet<String>(
- Arrays
- .asList(componentDirectives));
-
- static final Pattern VALID_PROPERTY_TYPES = Pattern
- .compile("(String|Long|Double|Float|Integer|Byte|Character|Boolean|Short)");
-
- String DEFAULT_BND_EXTENSION = ".bnd";
- String DEFAULT_JAR_EXTENSION = ".jar";
- String DEFAULT_BAR_EXTENSION = ".bar";
- String[] METAPACKAGES = { "META-INF",
- "OSGI-INF", "OSGI-OPT" };
-
- int STRATEGY_HIGHEST = 1;
- int STRATEGY_LOWEST = -1;
-
- String CURRENT_VERSION = "@";
- String CURRENT_PACKAGE = "@package";
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java
deleted file mode 100644
index 771dbf7..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/EmbeddedResource.java
+++ /dev/null
@@ -1,88 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.util.zip.*;
-
-public class EmbeddedResource implements Resource {
- byte data[];
- long lastModified;
- String extra;
-
- public EmbeddedResource(byte data[], long lastModified) {
- this.data = data;
- this.lastModified = lastModified;
- }
-
- public InputStream openInputStream() throws FileNotFoundException {
- return new ByteArrayInputStream(data);
- }
-
- public void write(OutputStream out) throws IOException {
- out.write(data);
- }
-
- public String toString() {
- return ":" + data.length + ":";
- }
-
- public static void build(Jar jar, InputStream in, long lastModified) throws IOException {
- ZipInputStream jin = new ZipInputStream(in);
- ZipEntry entry = jin.getNextEntry();
- while (entry != null) {
- if (!entry.isDirectory()) {
- byte data[] = collect(jin);
- jar.putResource(entry.getName(), new EmbeddedResource(data, lastModified), true);
- }
- entry = jin.getNextEntry();
- }
- jin.close();
- }
-
- /**
- * Convenience method to turn an inputstream into a byte array. The method
- * uses a recursive algorithm to minimize memory usage.
- *
- * @param in stream with data
- * @param offset where we are in the stream
- * @returns byte array filled with data
- */
- static byte[] collect(InputStream in) throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- copy(in,out);
- return out.toByteArray();
- }
-
- static void copy(InputStream in, OutputStream out) throws IOException {
- int available = in.available();
- if ( available <= 10000)
- available = 64000;
- byte [] buffer = new byte[available];
- int size;
- while ( (size=in.read(buffer))>0)
- out.write(buffer,0,size);
- }
-
- public long lastModified() {
- return lastModified;
- }
-
- public static void build(Jar sub, Resource resource) throws IOException {
- InputStream in = resource.openInputStream();
- build(sub,in, resource.lastModified());
- in.close();
- }
-
- public String getExtra() {
- return extra;
- }
-
- public void setExtra(String extra) {
- this.extra = extra;
- }
-
- public long size() {
- return data.length;
- }
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java
deleted file mode 100644
index fa70e21..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/FileResource.java
+++ /dev/null
@@ -1,86 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.util.regex.Pattern;
-
-public class FileResource implements Resource {
- File file;
- String extra;
-
- public FileResource(File file) {
- this.file = file;
- }
-
- public InputStream openInputStream() throws FileNotFoundException {
- return new FileInputStream(file);
- }
-
- public static void build(Jar jar, File directory, Pattern doNotCopy) {
- traverse(
- jar,
- directory.getAbsolutePath().length(),
- directory,
- doNotCopy);
- }
-
- public String toString() {
- return ":" + file.getName() + ":";
- }
-
- public void write(OutputStream out) throws IOException {
- copy(this, out);
- }
-
- static synchronized void copy(Resource resource, OutputStream out)
- throws IOException {
- InputStream in = resource.openInputStream();
- try {
- byte buffer[] = new byte[20000];
- int size = in.read(buffer);
- while (size > 0) {
- out.write(buffer, 0, size);
- size = in.read(buffer);
- }
- }
- finally {
- in.close();
- }
- }
-
- static void traverse(Jar jar, int rootlength, File directory,
- Pattern doNotCopy) {
- if (doNotCopy.matcher(directory.getName()).matches())
- return;
-
- File files[] = directory.listFiles();
- for (int i = 0; i < files.length; i++) {
- if (files[i].isDirectory())
- traverse(jar, rootlength, files[i], doNotCopy);
- else {
- String path = files[i].getAbsolutePath().substring(
- rootlength + 1);
- if (File.separatorChar != '/')
- path = path.replace(File.separatorChar, '/');
- jar.putResource(path, new FileResource(files[i]), true);
- }
- }
- }
-
- public long lastModified() {
- return file.lastModified();
- }
-
- public String getExtra() {
- return extra;
- }
-
- public void setExtra(String extra) {
- this.extra = extra;
- }
-
- public long size() {
- return (int) file.length();
- }
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
deleted file mode 100644
index b78cc57..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
+++ /dev/null
@@ -1,113 +0,0 @@
-/*
- * $Header: /cvs/xierpa/aQute.util.jar/src/aQute/lib/osgi/Instruction.java,v 1.1 2007-01-03 19:54:32 pkriens Exp $
- *
- * Copyright (c) OSGi Alliance (2006). All Rights Reserved.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- */
-
-package aQute.lib.osgi;
-
-import java.util.regex.*;
-
-public class Instruction {
- Pattern pattern;
- String instruction;
- boolean negated;
- boolean optional;
-
- public Instruction(String instruction, boolean negated) {
- this.instruction = instruction;
- this.negated = negated;
- }
-
- public boolean matches(String value) {
- return getMatcher(value).matches();
- }
-
- public boolean isNegated() {
- return negated;
- }
-
- public String getPattern() {
- return instruction;
- }
-
- /**
- * Convert a string based pattern to a regular expression based pattern.
- * This is called an instruction, this object makes it easier to handle the
- * different cases
- *
- * @param string
- * @return
- */
- public static Instruction getPattern(String string) {
- boolean negated = false;
- if (string.startsWith("!")) {
- negated = true;
- string = string.substring(1);
- }
- StringBuffer sb = new StringBuffer();
- for (int c = 0; c < string.length(); c++) {
- switch (string.charAt(c)) {
- case '.':
- sb.append("\\.");
- break;
- case '*':
- sb.append(".*");
- break;
- case '?':
- sb.append(".?");
- break;
- default:
- sb.append(string.charAt(c));
- break;
- }
- }
- string = sb.toString();
- if (string.endsWith("\\..*")) {
- sb.append("|");
- sb.append(string.substring(0, string.length() - 4));
- }
- return new Instruction(sb.toString(), negated);
- }
-
- public String toString() {
- return getPattern();
- }
-
- public Matcher getMatcher(String value) {
- if (pattern == null) {
- pattern = Pattern.compile(instruction);
- }
- return pattern.matcher(value);
- }
-
- public int hashCode() {
- return instruction.hashCode();
- }
-
- public boolean equals(Object other) {
- return other != null && (other instanceof Instruction)
- && instruction.equals(((Instruction) other).instruction);
- }
-
- public void setOptional() {
- optional = true;
- }
-
- public boolean isOptional() {
- return optional;
- }
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java b/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
deleted file mode 100644
index fe34cc5..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Jar.java
+++ /dev/null
@@ -1,408 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-import java.util.regex.*;
-import java.util.zip.*;
-
-import aQute.libg.reporter.*;
-
-public class Jar implements Closeable {
- public static final Object[] EMPTY_ARRAY = new Jar[0];
- Map<String, Resource> resources = new TreeMap<String, Resource>();
- Map<String, Map<String, Resource>> directories = new TreeMap<String, Map<String, Resource>>();
- Manifest manifest;
- boolean manifestFirst;
- String name;
- File source;
- ZipFile zipFile;
- long lastModified;
- String lastModifiedReason;
- Reporter reporter;
-
- public Jar(String name) {
- this.name = name;
- }
-
- public Jar(String name, File dirOrFile) throws ZipException, IOException {
- this(name);
- source = dirOrFile;
- if (dirOrFile.isDirectory())
- FileResource.build(this, dirOrFile, Analyzer.doNotCopy);
- else {
- zipFile = ZipResource.build(this, dirOrFile);
- }
- }
-
- public Jar(String name, InputStream in, long lastModified)
- throws IOException {
- this(name);
- EmbeddedResource.build(this, in, lastModified);
- }
-
- public Jar(String name, String path) throws IOException {
- this(name);
- File f = new File(path);
- InputStream in = new FileInputStream(f);
- EmbeddedResource.build(this, in, f.lastModified());
- in.close();
- }
-
- public Jar(File jar) throws IOException {
- this(getName(jar), jar);
- }
-
- /**
- * Make the JAR file name the project name if we get a src or bin directory.
- *
- * @param f
- * @return
- */
- private static String getName(File f) {
- f = f.getAbsoluteFile();
- String name = f.getName();
- if (name.equals("bin") || name.equals("src"))
- return f.getParentFile().getName();
- else {
- if ( name.endsWith(".jar"))
- name = name.substring(0, name.length()-4);
- return name;
- }
- }
-
- public Jar(String string, InputStream resourceAsStream) throws IOException {
- this(string, resourceAsStream, 0);
- }
-
- public void setName(String name) {
- this.name = name;
- }
-
- public String toString() {
- return "Jar:" + name;
- }
-
- public boolean putResource(String path, Resource resource) {
- return putResource(path, resource, true);
- }
-
- public boolean putResource(String path, Resource resource, boolean overwrite) {
- updateModified(resource.lastModified(), path);
-
- if (path.equals("META-INF/MANIFEST.MF")) {
- manifest = null;
- if (resources.isEmpty())
- manifestFirst = true;
- }
- String dir = getDirectory(path);
- Map<String, Resource> s = directories.get(dir);
- if (s == null) {
- s = new TreeMap<String, Resource>();
- directories.put(dir, s);
- int n = dir.lastIndexOf('/');
- while (n > 0) {
- String dd = dir.substring(0, n);
- if (directories.containsKey(dd))
- break;
- directories.put(dd, null);
- n = dd.lastIndexOf('/');
- }
- }
- boolean duplicate = s.containsKey(path);
- if (!duplicate || overwrite) {
- resources.put(path, resource);
- s.put(path, resource);
- }
- return duplicate;
- }
-
- public Resource getResource(String path) {
- return resources.get(path);
- }
-
- private String getDirectory(String path) {
- int n = path.lastIndexOf('/');
- if (n < 0)
- return "";
-
- return path.substring(0, n);
- }
-
- public Map<String, Map<String, Resource>> getDirectories() {
- return directories;
- }
-
- public Map<String, Resource> getResources() {
- return resources;
- }
-
- public boolean addDirectory(Map<String, Resource> directory,
- boolean overwrite) {
- boolean duplicates = false;
- if (directory == null)
- return false;
-
- for (Map.Entry<String, Resource> entry : directory.entrySet()) {
- String key = entry.getKey();
- if (!key.endsWith(".java")) {
- duplicates |= putResource(key, (Resource) entry.getValue(),
- overwrite);
- }
- }
- return duplicates;
- }
-
- public Manifest getManifest() throws IOException {
- if (manifest == null) {
- Resource manifestResource = getResource("META-INF/MANIFEST.MF");
- if (manifestResource != null) {
- InputStream in = manifestResource.openInputStream();
- manifest = new Manifest(in);
- in.close();
- }
- }
- return manifest;
- }
-
- public boolean exists(String path) {
- return resources.containsKey(path);
- }
-
- public void setManifest(Manifest manifest) {
- manifestFirst = true;
- this.manifest = manifest;
- }
-
- public void write(File file) throws Exception {
- try {
- OutputStream out = new FileOutputStream(file);
- write(out);
- out.close();
- return;
-
- } catch (Exception t) {
- file.delete();
- throw t;
- }
- }
-
- public void write(String file) throws Exception {
- write(new File(file));
- }
-
- public void write(OutputStream out) throws IOException {
- JarOutputStream jout = new JarOutputStream(out);
- Set<String> done = new HashSet<String>();
-
- Set<String> directories = new HashSet<String>();
- doManifest(done, jout);
- for (Map.Entry<String, Resource> entry : getResources().entrySet()) {
- // Skip metainf contents
- if (!done.contains(entry.getKey()))
- writeResource(jout, directories, (String) entry.getKey(),
- (Resource) entry.getValue());
- }
- jout.finish();
- }
-
- private void doManifest(Set<String> done, JarOutputStream jout)
- throws IOException {
- JarEntry ze = new JarEntry("META-INF/MANIFEST.MF");
- jout.putNextEntry(ze);
- writeManifest(jout);
- jout.closeEntry();
- done.add(ze.getName());
- }
-
-
- /**
- * Cleanup the manifest for writing. Cleaning up consists of
- * adding a space after any \n to prevent the manifest to see
- * this newline as a delimiter.
- *
- * @param out Output
- * @throws IOException
- */
-
- public void writeManifest(OutputStream out) throws IOException {
- writeManifest(getManifest(), out);
- }
-
- public static void writeManifest(Manifest manifest, OutputStream out ) throws IOException {
- manifest = clean(manifest);
- manifest.write(out);
- }
-
- private static Manifest clean(Manifest org) {
- Manifest result = new Manifest();
- for (Map.Entry<?,?> entry : org.getMainAttributes().entrySet()) {
- String nice = clean((String) entry.getValue());
- result.getMainAttributes().put(entry.getKey(),
- nice);
- }
- for (String name : org.getEntries().keySet() ) {
- Attributes attrs = result.getAttributes(name);
- if ( attrs == null ) {
- attrs = new Attributes();
- result.getEntries().put(name, attrs);
- }
-
- for (Map.Entry<?,?> entry : org.getAttributes(name).entrySet()) {
- String nice = clean((String) entry.getValue());
- attrs.put(
- (Attributes.Name) entry.getKey(), nice);
- }
- }
- return result;
- }
-
-
-
- private static String clean(String s) {
- if (s.indexOf('\n') < 0)
- return s;
-
- StringBuffer sb = new StringBuffer(s);
- for (int i = 0; i < sb.length(); i++) {
- if (sb.charAt(i) == '\n')
- sb.insert(++i, ' ');
- }
- return sb.toString();
- }
-
-
- private void writeResource(JarOutputStream jout, Set<String> directories,
- String path, Resource resource) throws IOException {
- if (resource == null)
- return;
-
- createDirectories(directories, jout, path);
- ZipEntry ze = new ZipEntry(path);
- ze.setMethod(ZipEntry.DEFLATED);
- long lastModified = resource.lastModified();
- if (lastModified == 0L) {
- lastModified = System.currentTimeMillis();
- }
- ze.setTime(lastModified);
- if (resource.getExtra() != null)
- ze.setExtra(resource.getExtra().getBytes());
- jout.putNextEntry(ze);
- try {
- resource.write(jout);
- } catch (Exception e) {
- throw new IllegalArgumentException("Cannot write resource: " + path
- + " " + e);
- }
- jout.closeEntry();
- }
-
- void createDirectories(Set<String> directories, JarOutputStream zip,
- String name) throws IOException {
- int index = name.lastIndexOf('/');
- if (index > 0) {
- String path = name.substring(0, index);
- if (directories.contains(path))
- return;
- createDirectories(directories, zip, path);
- ZipEntry ze = new ZipEntry(path + '/');
- zip.putNextEntry(ze);
- zip.closeEntry();
- directories.add(path);
- }
- }
-
- public String getName() {
- return name;
- }
-
- /**
- * Add all the resources in the given jar that match the given filter.
- *
- * @param sub
- * the jar
- * @param filter
- * a pattern that should match the resoures in sub to be added
- */
- public boolean addAll(Jar sub, Pattern filter) {
- boolean dupl = false;
- for (String name : sub.getResources().keySet()) {
- if ("META-INF/MANIFEST.MF".equals(name))
- continue;
-
- if (filter == null || filter.matcher(name).matches())
- dupl |= putResource(name, sub.getResource(name), true);
- }
- return dupl;
- }
-
- public void close() {
- if (zipFile != null)
- try {
- zipFile.close();
- } catch (IOException e) {
- // Ignore
- }
- resources = null;
- directories = null;
- manifest = null;
- source = null;
- }
-
- public long lastModified() {
- return lastModified;
- }
-
- public void updateModified(long time, String reason) {
- if (time > lastModified) {
- lastModified = time;
- lastModifiedReason = reason;
- }
- }
-
- public void setReporter(Reporter reporter) {
- this.reporter = reporter;
- }
-
- public boolean hasDirectory(String path) {
- return directories.get(path) != null;
- }
-
- public List<String> getPackages() {
- List<String> list = new ArrayList<String>(directories.size());
-
- for (Iterator<String> i = directories.keySet().iterator(); i.hasNext();) {
- String path = i.next();
- String pack = path.replace('/', '.');
- list.add(pack);
- }
- return list;
- }
-
- public File getSource() {
- return source;
- }
-
- public boolean addAll(Jar src) {
- return addAll(src, null);
- }
-
- public boolean rename(String oldPath, String newPath) {
- Resource resource = remove(oldPath);
- if (resource == null)
- return false;
-
- return putResource(newPath, resource);
- }
-
- public Resource remove(String path) {
- Resource resource = resources.remove(path);
- String dir = getDirectory(path);
- Map<String, Resource> mdir = directories.get(dir);
- // must be != null
- mdir.remove(path);
- return resource;
- }
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java
deleted file mode 100644
index b633de1..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/JarResource.java
+++ /dev/null
@@ -1,42 +0,0 @@
-package aQute.lib.osgi;
-
-import java.io.*;
-
-public class JarResource implements Resource {
- Jar jar;
- String extra;
-
- public JarResource(Jar jar ) {
- this.jar = jar;
- }
-
- public String getExtra() {
- return extra;
- }
-
- public long lastModified() {
- return jar.lastModified();
- }
-
-
- public void write(OutputStream out) throws IOException {
- jar.write(out);
- }
-
- public InputStream openInputStream() throws IOException {
- ByteArrayOutputStream out = new ByteArrayOutputStream();
- write(out);
- out.close();
- ByteArrayInputStream in = new ByteArrayInputStream(out.toByteArray());
- return in;
- }
-
- public void setExtra(String extra) {
- this.extra = extra;
- }
-
- public Jar getJar() {
- return jar;
- }
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java b/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java
deleted file mode 100644
index 22748ae..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Macro.java
+++ /dev/null
@@ -1,832 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.lang.reflect.*;
-import java.net.*;
-import java.text.*;
-import java.util.*;
-import java.util.regex.*;
-
-import aQute.libg.sed.*;
-import aQute.libg.version.*;
-
-/**
- * Provide a macro processor. This processor can replace variables in strings
- * based on a properties and a domain. The domain can implement functions that
- * start with a "_" and take args[], the names of these functions are available
- * as functions in the macro processor (without the _). Macros can nest to any
- * depth but may not contain loops.
- *
- */
-public class Macro implements Replacer {
- Properties properties;
- Processor domain;
- Object targets[];
- boolean flattening;
-
- public Macro(Properties properties, Processor domain, Object... targets) {
- this.properties = properties;
- this.domain = domain;
- this.targets = targets;
- if (targets != null) {
- for (Object o : targets) {
- assert o != null;
- }
- }
- }
-
- public Macro(Processor processor) {
- this(new Properties(), processor);
- }
-
- public String process(String line) {
- return process(line, null);
- }
-
- String process(String line, Link link) {
- StringBuffer sb = new StringBuffer();
- process(line, 0, '\u0000', '\u0000', sb, link);
- return sb.toString();
- }
-
- int process(CharSequence org, int index, char begin, char end,
- StringBuffer result, Link link) {
- StringBuilder line = new StringBuilder(org);
- int nesting = 1;
-
- StringBuffer variable = new StringBuffer();
- outer: while (index < line.length()) {
- char c1 = line.charAt(index++);
- if (c1 == end) {
- if (--nesting == 0) {
- result.append(replace(variable.toString(), link));
- return index;
- }
- } else if (c1 == begin)
- nesting++;
- else if (c1 == '\\' && index < line.length() - 1
- && line.charAt(index) == '$') {
- // remove the escape backslash and interpret the dollar as a
- // literal
- index++;
- variable.append('$');
- continue outer;
- } else if (c1 == '$' && index < line.length() - 2) {
- char c2 = line.charAt(index);
- char terminator = getTerminator(c2);
- if (terminator != 0) {
- index = process(line, index + 1, c2, terminator, variable,
- link);
- continue outer;
- }
- }
- variable.append(c1);
- }
- result.append(variable);
- return index;
- }
-
- char getTerminator(char c) {
- switch (c) {
- case '(':
- return ')';
- case '[':
- return ']';
- case '{':
- return '}';
- case '<':
- return '>';
- case '\u00ab': // Guillemet double << >>
- return '\u00bb';
- case '\u2039': // Guillemet single
- return '\u203a';
- }
- return 0;
- }
-
- protected String replace(String key, Link link) {
- if (link != null && link.contains(key))
- return "${infinite:" + link.toString() + "}";
-
- if (key != null) {
- key = key.trim();
- if (key.length() > 0) {
- String value = (String) properties.getProperty(key);
- if (value != null)
- return process(value, new Link(link, key));
-
- value = doCommands(key);
- if (value != null)
- return process(value, new Link(link, key));
-
- if (key != null && key.trim().length() > 0) {
- value = System.getProperty(key);
- if (value != null)
- return value;
- }
- if (!flattening)
- domain.warning("No translation found for macro: " + key);
- } else {
- domain.warning("Found empty macro key");
- }
- } else {
- domain.warning("Found null macro key");
- }
- return "${" + key + "}";
- }
-
- /**
- * Parse the key as a command. A command consist of parameters separated by
- * ':'.
- *
- * @param key
- * @return
- */
- static Pattern commands = Pattern.compile("(?<!\\\\);");
-
- private String doCommands(String key) {
- String[] args = commands.split(key);
- if (args == null || args.length == 0)
- return null;
-
- for (int i = 0; i < args.length; i++)
- if (args[i].indexOf('\\') >= 0)
- args[i] = args[i].replaceAll("\\\\;", ";");
-
- Processor rover = domain;
- while (rover != null) {
- String result = doCommand(rover, args[0], args);
- if (result != null)
- return result;
-
- rover = rover.getParent();
- }
-
- for (int i = 0; targets != null && i < targets.length; i++) {
- String result = doCommand(targets[i], args[0], args);
- if (result != null)
- return result;
- }
-
- return doCommand(this, args[0], args);
- }
-
- private String doCommand(Object target, String method, String[] args) {
- if (target == null)
- ; // System.out.println("Huh? Target should never be null " +
- // domain);
- else {
- String cname = "_" + method.replaceAll("-", "_");
- try {
- Method m = target.getClass().getMethod(cname,
- new Class[] { String[].class });
- return (String) m.invoke(target, new Object[] { args });
- } catch (NoSuchMethodException e) {
- // Ignore
- } catch (InvocationTargetException e) {
- domain.warning("Exception in replace: " + e.getCause());
- e.printStackTrace();
- } catch (Exception e) {
- domain.warning("Exception in replace: " + e + " method="
- + method);
- e.printStackTrace();
- }
- }
- return null;
- }
-
- /**
- * Return a unique list where the duplicates are removed.
- *
- * @param args
- * @return
- */
- static String _uniqHelp = "${uniq;<list> ...}";
-
- public String _uniq(String args[]) {
- verifyCommand(args, _uniqHelp, null, 1, Integer.MAX_VALUE);
- Set<String> set = new LinkedHashSet<String>();
- for (int i = 1; i < args.length; i++) {
- Processor.split(args[i], set);
- }
- return Processor.join(set, ",");
- }
-
- public String _filter(String args[]) {
- return filter(args, false);
- }
-
- public String _filterout(String args[]) {
- return filter(args, true);
-
- }
-
- static String _filterHelp = "${%s;<list>;<regex>}";
-
- String filter(String[] args, boolean include) {
- verifyCommand(args, String.format(_filterHelp, args[0]), null, 3, 3);
-
- Collection<String> list = new ArrayList<String>(Processor
- .split(args[1]));
- Pattern pattern = Pattern.compile(args[2]);
-
- for (Iterator<String> i = list.iterator(); i.hasNext();) {
- if (pattern.matcher(i.next()).matches() == include)
- i.remove();
- }
- return Processor.join(list);
- }
-
- static String _sortHelp = "${sort;<list>...}";
-
- public String _sort(String args[]) {
- verifyCommand(args, _sortHelp, null, 2, Integer.MAX_VALUE);
-
- List<String> result = new ArrayList<String>();
- for (int i = 1; i < args.length; i++) {
- Processor.split(args[i], result);
- }
- Collections.sort(result);
- return Processor.join(result);
- }
-
- static String _joinHelp = "${join;<list>...}";
-
- public String _join(String args[]) {
-
- verifyCommand(args, _joinHelp, null, 1, Integer.MAX_VALUE);
-
- List<String> result = new ArrayList<String>();
- for (int i = 1; i < args.length; i++) {
- Processor.split(args[i], result);
- }
- return Processor.join(result);
- }
-
- static String _ifHelp = "${if;<condition>;<iftrue> [;<iffalse>] }";
-
- public String _if(String args[]) {
- verifyCommand(args, _ifHelp, null, 3, 4);
- String condition = args[1].trim();
- if (condition.length() != 0)
- return args[2];
- if (args.length > 3)
- return args[3];
- else
- return "";
- }
-
- public String _now(String args[]) {
- return new Date().toString();
- }
-
- public static String _fmodifiedHelp = "${fmodified;<list of filenames>...}, return latest modification date";
-
- public String _fmodified(String args[]) throws Exception {
- verifyCommand(args, _fmodifiedHelp, null, 2, Integer.MAX_VALUE);
-
- long time = 0;
- Collection<String> names = new ArrayList<String>();
- for (int i = 1; i < args.length; i++) {
- Processor.split(args[i], names);
- }
- for (String name : names) {
- File f = new File(name);
- if (f.exists() && f.lastModified() > time)
- time = f.lastModified();
- }
- return "" + time;
- }
-
- public String _long2date(String args[]) {
- try {
- return new Date(Long.parseLong(args[1])).toString();
- } catch (Exception e) {
- e.printStackTrace();
- }
- return "not a valid long";
- }
-
- public String _literal(String args[]) {
- if (args.length != 2)
- throw new RuntimeException(
- "Need a value for the ${literal;<value>} macro");
- return "${" + args[1] + "}";
- }
-
- public String _def(String args[]) {
- if (args.length != 2)
- throw new RuntimeException(
- "Need a value for the ${def;<value>} macro");
-
- String value = properties.getProperty(args[1]);
- if (value == null)
- return "";
- else
- return value;
- }
-
- /**
- *
- * replace ; <list> ; regex ; replace
- *
- * @param args
- * @return
- */
- public String _replace(String args[]) {
- if (args.length != 4) {
- domain.warning("Invalid nr of arguments to replace "
- + Arrays.asList(args));
- return null;
- }
-
- String list[] = args[1].split("\\s*,\\s*");
- StringBuffer sb = new StringBuffer();
- String del = "";
- for (int i = 0; i < list.length; i++) {
- String element = list[i].trim();
- if (!element.equals("")) {
- sb.append(del);
- sb.append(element.replaceAll(args[2], args[3]));
- del = ", ";
- }
- }
-
- return sb.toString();
- }
-
- public String _warning(String args[]) {
- for (int i = 1; i < args.length; i++) {
- domain.warning(process(args[i]));
- }
- return "";
- }
-
- public String _error(String args[]) {
- for (int i = 1; i < args.length; i++) {
- domain.error(process(args[i]));
- }
- return "";
- }
-
- /**
- * toclassname ; <path>.class ( , <path>.class ) *
- *
- * @param args
- * @return
- */
- static String _toclassnameHelp = "${classname;<list of class names>}, convert class paths to FQN class names ";
-
- public String _toclassname(String args[]) {
- verifyCommand(args, _toclassnameHelp, null, 2, 2);
- Collection<String> paths = Processor.split(args[1]);
-
- List<String> names = new ArrayList<String>(paths.size());
- for (String path : paths) {
- if (path.endsWith(".class")) {
- String name = path.substring(0, path.length() - 6).replace('/',
- '.');
- names.add(name);
- } else if (path.endsWith(".java")) {
- String name = path.substring(0, path.length() - 5).replace('/',
- '.');
- names.add(name);
- } else {
- domain
- .warning("in toclassname, "
- + args[1]
- + " is not a class path because it does not end in .class");
- }
- }
- return Processor.join(names, ",");
- }
-
- /**
- * toclassname ; <path>.class ( , <path>.class ) *
- *
- * @param args
- * @return
- */
-
- static String _toclasspathHelp = "${toclasspath;<list>}, convert a list of class names to paths";
-
- public String _toclasspath(String args[]) {
- verifyCommand(args, _toclasspathHelp, null, 2, 2);
-
- Collection<String> names = Processor.split(args[1]);
- Collection<String> paths = new ArrayList<String>(names.size());
- for (String name : names) {
- String path = name.replace('.', '/') + ".class";
- paths.add(path);
- }
- return Processor.join(paths, ",");
- }
-
- public String _dir(String args[]) {
- if (args.length < 2) {
- domain.warning("Need at least one file name for ${dir;...}");
- return null;
- } else {
- String del = "";
- StringBuffer sb = new StringBuffer();
- for (int i = 1; i < args.length; i++) {
- File f = new File(args[i]).getAbsoluteFile();
- if (f.exists() && f.getParentFile().exists()) {
- sb.append(del);
- sb.append(f.getParentFile().getAbsolutePath());
- del = ",";
- }
- }
- return sb.toString();
- }
-
- }
-
- public String _basename(String args[]) {
- if (args.length < 2) {
- domain.warning("Need at least one file name for ${basename;...}");
- return null;
- } else {
- String del = "";
- StringBuffer sb = new StringBuffer();
- for (int i = 1; i < args.length; i++) {
- File f = new File(args[i]).getAbsoluteFile();
- if (f.exists() && f.getParentFile().exists()) {
- sb.append(del);
- sb.append(f.getName());
- del = ",";
- }
- }
- return sb.toString();
- }
-
- }
-
- public String _isfile(String args[]) {
- if (args.length < 2) {
- domain.warning("Need at least one file name for ${isfile;...}");
- return null;
- } else {
- boolean isfile = true;
- for (int i = 1; i < args.length; i++) {
- File f = new File(args[i]).getAbsoluteFile();
- isfile &= f.isFile();
- }
- return isfile ? "true" : "false";
- }
-
- }
-
- public String _isdir(String args[]) {
- if (args.length < 2) {
- domain.warning("Need at least one file name for ${isdir;...}");
- return null;
- } else {
- boolean isdir = true;
- for (int i = 1; i < args.length; i++) {
- File f = new File(args[i]).getAbsoluteFile();
- isdir &= f.isDirectory();
- }
- return isdir ? "true" : "false";
- }
-
- }
-
- public String _tstamp(String args[]) {
- String format = "yyyyMMddhhmm";
- long now = System.currentTimeMillis();
-
- if (args.length > 1) {
- format = args[1];
- if (args.length > 2) {
- now = Long.parseLong(args[2]);
- if (args.length > 3) {
- domain.warning("Too many arguments for tstamp: "
- + Arrays.toString(args));
- }
- }
- }
- SimpleDateFormat sdf = new SimpleDateFormat(format);
- return sdf.format(new Date(now));
- }
-
- /**
- * Wildcard a directory. The lists can contain Instruction that are matched
- * against the given directory
- *
- * ${wc;<dir>;<list>(;<list>)*}
- *
- * @author aqute
- *
- */
-
- public String _lsr(String args[]) {
- return ls(args, true);
- }
-
- public String _lsa(String args[]) {
- return ls(args, false);
- }
-
- String ls(String args[], boolean relative) {
- if (args.length < 2)
- throw new IllegalArgumentException(
- "the ${ls} macro must at least have a directory as parameter");
-
- File dir = new File(args[1]);
- if (!dir.isAbsolute())
- throw new IllegalArgumentException(
- "the ${ls} macro directory parameter is not absolute: "
- + dir);
-
- if (!dir.exists())
- throw new IllegalArgumentException(
- "the ${ls} macro directory parameter does not exist: "
- + dir);
-
- if (!dir.isDirectory())
- throw new IllegalArgumentException(
- "the ${ls} macro directory parameter points to a file instead of a directory: "
- + dir);
-
- String[] files = dir.list();
- List<String> result;
-
- if (args.length < 3) {
- result = Arrays.asList(files);
- } else
- result = new ArrayList<String>();
-
- for (int i = 2; i < args.length; i++) {
- String parts[] = args[i].split("\\s*,\\s*");
- for (String pattern : parts) {
- // So make it in to an instruction
- Instruction instr = Instruction.getPattern(pattern);
-
- // For each project, match it against the instruction
- for (int f = 0; f < files.length; f++) {
- if (files[f] != null) {
- if (instr.matches(files[f])) {
- if (!instr.isNegated()) {
- if (relative)
- result.add(files[f]);
- else
- result.add(new File(dir, files[f])
- .getAbsolutePath());
- }
- files[f] = null;
- }
- }
- }
- }
- }
- return Processor.join(result, ",");
- }
-
- public String _currenttime(String args[]) {
- return Long.toString(System.currentTimeMillis());
- }
-
- /**
- * Modify a version to set a version policy. Thed policy is a mask that is
- * mapped to a version.
- *
- * <pre>
- * + increment
- * - decrement
- * = maintain
- * ˜ discard
- *
- * ==+ = maintain major, minor, increment micro, discard qualifier
- * ˜˜˜= = just get the qualifier
- * version="[${version;==;${@}},${version;=+;${@}})"
- * </pre>
- *
- *
- *
- *
- * @param args
- * @return
- */
- static String _versionHelp = "${version;<mask>;<version>}, modify a version\n"
- + "<mask> ::= [ M [ M [ M [ MQ ]]]\n"
- + "M ::= '+' | '-' | MQ\n"
- + "MQ ::= '~' | '='";
- static Pattern _versionPattern[] = new Pattern[] { null, null,
- Pattern.compile("[-+=~]{0,3}[=~]?"), Verifier.VERSION };
-
- public String _version(String args[]) {
- verifyCommand(args, _versionHelp, null, 3, 3);
-
- String mask = args[1];
-
- Version version = new Version(args[2]);
- StringBuilder sb = new StringBuilder();
- String del = "";
-
- for (int i = 0; i < mask.length(); i++) {
- char c = mask.charAt(i);
- String result = null;
- if (c != '~') {
- if (i == 3) {
- result = version.getQualifier();
- } else {
- int x = version.get(i);
- switch (c) {
- case '+':
- x++;
- break;
- case '-':
- x--;
- break;
- case '=':
- break;
- }
- result = Integer.toString(x);
- }
- if (result != null) {
- sb.append(del);
- del = ".";
- sb.append(result);
- }
- }
- }
- return sb.toString();
- }
-
- /**
- * System command. Execute a command and insert the result.
- *
- * @param args
- * @param help
- * @param patterns
- * @param low
- * @param high
- */
- public String _system(String args[]) throws Exception {
- verifyCommand(args,
- "${system;<command>[;<in>]}, execute a system command", null,
- 2, 3);
- String command = args[1];
- String input = null;
-
- if (args.length > 2) {
- input = args[2];
- }
-
- Process process = Runtime.getRuntime().exec(command, null,
- domain.getBase());
- if (input != null) {
- process.getOutputStream().write(input.getBytes("UTF-8"));
- }
- process.getOutputStream().close();
-
- String s = getString(process.getInputStream());
- process.getInputStream().close();
- int exitValue = process.waitFor();
- if (exitValue != 0) {
- domain.error("System command " + command + " failed with "
- + exitValue);
- }
- return s.trim();
- }
-
- /**
- * Get the contents of a file.
- *
- * @param in
- * @return
- * @throws IOException
- */
-
- public String _cat(String args[]) throws IOException {
- verifyCommand(args, "${cat;<in>}, get the content of a file", null, 2,
- 2);
- File f = domain.getFile(args[1]);
- if (f.isFile()) {
- InputStream in = new FileInputStream(f);
- return getString(in);
- } else if (f.isDirectory()) {
- return Arrays.toString(f.list());
- } else {
- try {
- URL url = new URL(args[1]);
- InputStream in = url.openStream();
- return getString(in);
- } catch (MalformedURLException mfue) {
- // Ignore here
- }
- return null;
- }
- }
-
- public static String getString(InputStream in) throws IOException {
- try {
- StringBuilder sb = new StringBuilder();
- BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
- String line = null;
- while ((line = rdr.readLine()) != null) {
- sb.append(line);
- sb.append("\n");
- }
- return sb.toString();
- } finally {
- in.close();
- }
- }
-
- public static void verifyCommand(String args[], String help,
- Pattern[] patterns, int low, int high) {
- String message = "";
- if (args.length > high) {
- message = "too many arguments";
- } else if (args.length < low) {
- message = "too few arguments";
- } else {
- for (int i = 0; patterns != null && i < patterns.length
- && i < args.length - 1; i++) {
- if (patterns[i] != null
- && !patterns[i].matcher(args[i + 1]).matches()) {
- message += String.format(
- "Argument %s (%s) does not match %s\n", i, args[i],
- patterns[i].pattern());
- }
- }
- }
- if (message.length() != 0) {
- StringBuilder sb = new StringBuilder();
- String del = "${";
- for (String arg : args) {
- sb.append(del);
- sb.append(arg);
- del = ";";
- }
- sb.append("}, is not understood. ");
- sb.append(message);
- throw new IllegalArgumentException(sb.toString());
- }
- }
-
- // Helper class to track expansion of variables
- // on the stack.
- static class Link {
- Link previous;
- String key;
-
- public Link(Link previous, String key) {
- this.previous = previous;
- this.key = key;
- }
-
- public boolean contains(String key) {
- if (this.key.equals(key))
- return true;
-
- if (previous == null)
- return false;
-
- return previous.contains(key);
- }
-
- public String toString() {
- StringBuffer sb = new StringBuffer();
- String del = "[";
- for (Link r = this; r != null; r = r.previous) {
- sb.append(del);
- sb.append(r.key);
- del = ",";
- }
- sb.append("]");
- return sb.toString();
- }
- }
-
- /**
- * Take all the properties and translate them to actual values. This method
- * takes the set properties and traverse them over all entries, including
- * the default properties for that properties. The values no longer contain
- * macros.
- *
- * @return A new Properties with the flattened values
- */
- public Properties getFlattenedProperties() {
- // Some macros only work in a lower processor, so we
- // do not report unknown macros while flattening
- flattening = true;
- try {
- Properties flattened = new Properties();
- for (Enumeration<?> e = properties.propertyNames(); e
- .hasMoreElements();) {
- String key = (String) e.nextElement();
- if (!key.startsWith("_"))
- flattened.put(key, process(properties.getProperty(key)));
- }
- return flattened;
- } finally {
- flattening = false;
- }
- };
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/OpCodes.java b/bundleplugin/src/main/java/aQute/lib/osgi/OpCodes.java
deleted file mode 100644
index f0d3134..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/OpCodes.java
+++ /dev/null
@@ -1,1196 +0,0 @@
-package aQute.lib.osgi;
-
-public class OpCodes {
- final static short nop = 0x00; // [No change] performs
- // no
- // operation
- final static short aconst_null = 0x01; // ? null pushes a null
- // reference onto the stack
- final static short iconst_m1 = 0x02; // ? -1 loads the int
- // value -1
- // onto the stack
- final static short iconst_0 = 0x03; // ? 0 loads the int
- // value 0
- // onto the stack
- final static short iconst_1 = 0x04; // ? 1 loads the int
- // value 1
- // onto the stack
- final static short iconst_2 = 0x05; // ? 2 loads the int
- // value 2
- // onto the stack
- final static short iconst_3 = 0x06; // ? 3 loads the int
- // value 3
- // onto the stack
- final static short iconst_4 = 0x07; // ? 4 loads the int
- // value 4
- // onto the stack
- final static short iconst_5 = 0x08; // ? 5 loads the int
- // value 5
- // onto the stack
- final static short lconst_0 = 0x09; // ? 0L pushes the long
- // 0 onto
- // the stack
- final static short bipush = 0x10; // byte ? value pushes a
- // byte
- // onto the stack as an integer
- // value
- final static short sipush = 0x11; // byte1, byte2 ? value
- // pushes a
- // signed integer (byte1 << 8 +
- // byte2) onto the stack
- final static short ldc = 0x12; // index ? value pushes
- // a
- // constant #index from a
- // constant pool (String, int,
- // float or class type) onto the
- // stack
- final static short ldc_w = 0x13; // indexbyte1,
- // indexbyte2 ?
- // value pushes a constant
- // #index from a constant pool
- // (String, int, float or class
- // type) onto the stack (wide
- // index is constructed as
- // indexbyte1 << 8 + indexbyte2)
- final static short ldc2_w = 0x14; // indexbyte1,
- // indexbyte2 ?
- // value pushes a constant
- // #index from a constant pool
- // (double or long) onto the
- // stack (wide index is
- // constructed as indexbyte1 <<
- // 8 + indexbyte2)
- final static short iload = 0x15; // index ? value loads
- // an int
- // value from a variable #index
- final static short lload = 0x16; // index ? value load a
- // long
- // value from a local variable
- // #index
- final static short fload = 0x17; // index ? value loads a
- // float
- // value from a local variable
- // #index
- final static short dload = 0x18; // index ? value loads a
- // double
- // value from a local variable
- // #index
- final static short aload = 0x19; // index ? objectref
- // loads a
- // reference onto the stack from
- // a local variable #index
- final static short lload_2 = 0x20; // ? value load a long
- // value
- // from a local variable 2
- final static short lload_3 = 0x21; // ? value load a long
- // value
- // from a local variable 3
- final static short fload_0 = 0x22; // ? value loads a float
- // value
- // from local variable 0
- final static short fload_1 = 0x23; // ? value loads a float
- // value
- // from local variable 1
- final static short fload_2 = 0x24; // ? value loads a float
- // value
- // from local variable 2
- final static short fload_3 = 0x25; // ? value loads a float
- // value
- // from local variable 3
- final static short dload_0 = 0x26; // ? value loads a
- // double from
- // local variable 0
- final static short dload_1 = 0x27; // ? value loads a
- // double from
- // local variable 1
- final static short dload_2 = 0x28; // ? value loads a
- // double from
- // local variable 2
- final static short dload_3 = 0x29; // ? value loads a
- // double from
- // local variable 3
- final static short faload = 0x30; // arrayref, index ?
- // value loads
- // a float from an array
- final static short daload = 0x31; // arrayref, index ?
- // value loads
- // a double from an array
- final static short aaload = 0x32; // arrayref, index ?
- // value loads
- // onto the stack a reference
- // from an array
- final static short baload = 0x33; // arrayref, index ?
- // value loads
- // a byte or Boolean value from
- // an array
- final static short caload = 0x34; // arrayref, index ?
- // value loads
- // a char from an array
- final static short saload = 0x35; // arrayref, index ?
- // value load
- // short from array
- final static short istore = 0x36; // index value ? store
- // int value
- // into variable #index
- final static short lstore = 0x37; // index value ? store a
- // long
- // value in a local variable
- // #index
- final static short fstore = 0x38; // index value ? stores
- // a float
- // value into a local variable
- // #index
- final static short dstore = 0x39; // index value ? stores
- // a double
- // value into a local variable
- // #index
- final static short lstore_1 = 0x40; // value ? store a long
- // value in
- // a local variable 1
- final static short lstore_2 = 0x41; // value ? store a long
- // value in
- // a local variable 2
- final static short lstore_3 = 0x42; // value ? store a long
- // value in
- // a local variable 3
- final static short fstore_0 = 0x43; // value ? stores a
- // float value
- // into local variable 0
- final static short fstore_1 = 0x44; // value ? stores a
- // float value
- // into local variable 1
- final static short fstore_2 = 0x45; // value ? stores a
- // float value
- // into local variable 2
- final static short fstore_3 = 0x46; // value ? stores a
- // float value
- // into local variable 3
- final static short dstore_0 = 0x47; // value ? stores a
- // double into
- // local variable 0
- final static short dstore_1 = 0x48; // value ? stores a
- // double into
- // local variable 1
- final static short dstore_2 = 0x49; // value ? stores a
- // double into
- // local variable 2
- final static short lastore = 0x50; // arrayref, index,
- // value ?
- // store a long to an array
- final static short fastore = 0x51; // arreyref, index,
- // value ?
- // stores a float in an array
- final static short dastore = 0x52; // arrayref, index,
- // value ?
- // stores a double into an array
- final static short aastore = 0x53; // arrayref, index,
- // value ?
- // stores into a reference to an
- // array
- final static short bastore = 0x54; // arrayref, index,
- // value ?
- // stores a byte or Boolean
- // value into an array
- final static short castore = 0x55; // arrayref, index,
- // value ?
- // stores a char into an array
- final static short sastore = 0x56; // arrayref, index,
- // value ?
- // store short to array
- final static short pop = 0x57; // value ? discards the
- // top
- // value on the stack
- final static short pop2 = 0x58; // {value2, value1} ?
- // discards
- // the top two values on the
- // stack (or one value, if it is
- // a double or long)
- final static short dup = 0x59; // value ? value, value
- // duplicates the value on top
- // of the stack
- final static short iadd = 0x60; // value1, value2 ?
- // result adds
- // two ints together
- final static short ladd = 0x61; // value1, value2 ?
- // result add
- // two longs
- final static short fadd = 0x62; // value1, value2 ?
- // result adds
- // two floats
- final static short dadd = 0x63; // value1, value2 ?
- // result adds
- // two doubles
- final static short isub = 0x64; // value1, value2 ?
- // result int
- // subtract
- final static short lsub = 0x65; // value1, value2 ?
- // result
- // subtract two longs
- final static short fsub = 0x66; // value1, value2 ?
- // result
- // subtracts two floats
- final static short dsub = 0x67; // value1, value2 ?
- // result
- // subtracts a double from
- // another
- final static short imul = 0x68; // value1, value2 ?
- // result
- // multiply two integers
- final static short lmul = 0x69; // value1, value2 ?
- // result
- // multiplies two longs
- final static short irem = 0x70; // value1, value2 ?
- // result
- // logical int remainder
- final static short lrem = 0x71; // value1, value2 ?
- // result
- // remainder of division of two
- // longs
- final static short frem = 0x72; // value1, value2 ?
- // result gets
- // the remainder from a division
- // between two floats
- final static short drem = 0x73; // value1, value2 ?
- // result gets
- // the remainder from a division
- // between two doubles
- final static short ineg = 0x74; // value ? result negate
- // int
- final static short lneg = 0x75; // value ? result
- // negates a long
- final static short fneg = 0x76; // value ? result
- // negates a
- // float
- final static short dneg = 0x77; // value ? result
- // negates a
- // double
- final static short ishl = 0x78; // value1, value2 ?
- // result int
- // shift left
- final static short lshl = 0x79; // value1, value2 ?
- // result
- // bitwise shift left of a long
- // value1 by value2 positions
- final static short ior = 0x80; // value1, value2 ?
- // result
- // logical int or
- final static short lor = 0x81; // value1, value2 ?
- // result
- // bitwise or of two longs
- final static short ixor = 0x82; // value1, value2 ?
- // result int
- // xor
- final static short lxor = 0x83; // value1, value2 ?
- // result
- // bitwise exclusive or of two
- // longs
- final static short iinc = 0x84; // index, const [No
- // change]
- // increment local variable
- // #index by signed byte const
- final static short i2l = 0x85; // value ? result
- // converts an
- // int into a long
- final static short i2f = 0x86; // value ? result
- // converts an
- // int into a float
- final static short i2d = 0x87; // value ? result
- // converts an
- // int into a double
- final static short l2i = 0x88; // value ? result
- // converts a
- // long to an int
- final static short l2f = 0x89; // value ? result
- // converts a
- // long to a float
- final static short d2f = 0x90; // value ? result
- // converts a
- // double to a float
- final static short i2b = 0x91; // value ? result
- // converts an
- // int into a byte
- final static short i2c = 0x92; // value ? result
- // converts an
- // int into a character
- final static short i2s = 0x93; // value ? result
- // converts an
- // int into a short
- final static short lcmp = 0x94; // value1, value2 ?
- // result
- // compares two longs values
- final static short fcmpl = 0x95; // value1, value2 ?
- // result
- // compares two floats
- final static short fcmpg = 0x96; // value1, value2 ?
- // result
- // compares two floats
- final static short dcmpl = 0x97; // value1, value2 ?
- // result
- // compares two doubles
- final static short dcmpg = 0x98; // value1, value2 ?
- // result
- // compares two doubles
- final static short ifeq = 0x99; // branchbyte1,
- // branchbyte2
- // value ? if value is 0, branch
- // to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short lconst_1 = 0x0a; // ? 1L pushes the long
- // 1 onto
- // the stack
- final static short fconst_0 = 0x0b; // ? 0.0f pushes 0.0f on
- // the
- // stack
- final static short fconst_1 = 0x0c; // ? 1.0f pushes 1.0f on
- // the
- // stack
- final static short fconst_2 = 0x0d; // ? 2.0f pushes 2.0f on
- // the
- // stack
- final static short dconst_0 = 0x0e; // ? 0.0 pushes the
- // constant 0.0
- // onto the stack
- final static short dconst_1 = 0x0f; // ? 1.0 pushes the
- // constant 1.0
- // onto the stack
- final static short iload_0 = 0x1a; // ? value loads an int
- // value
- // from variable 0
- final static short iload_1 = 0x1b; // ? value loads an int
- // value
- // from variable 1
- final static short iload_2 = 0x1c; // ? value loads an int
- // value
- // from variable 2
- final static short iload_3 = 0x1d; // ? value loads an int
- // value
- // from variable 3
- final static short lload_0 = 0x1e; // ? value load a long
- // value
- // from a local variable 0
- final static short lload_1 = 0x1f; // ? value load a long
- // value
- // from a local variable 1
- final static short aload_0 = 0x2a; // ? objectref loads a
- // reference
- // onto the stack from local
- // variable 0
- final static short aload_1 = 0x2b; // ? objectref loads a
- // reference
- // onto the stack from local
- // variable 1
- final static short aload_2 = 0x2c; // ? objectref loads a
- // reference
- // onto the stack from local
- // variable 2
- final static short aload_3 = 0x2d; // ? objectref loads a
- // reference
- // onto the stack from local
- // variable 3
- final static short iaload = 0x2e; // arrayref, index ?
- // value loads
- // an int from an array
- final static short laload = 0x2f; // arrayref, index ?
- // value load
- // a long from an array
- final static short astore = 0x3a; // index objectref ?
- // stores a
- // reference into a local
- // variable #index
- final static short istore_0 = 0x3b; // value ? store int
- // value into
- // variable 0
- final static short istore_1 = 0x3c; // value ? store int
- // value into
- // variable 1
- final static short istore_2 = 0x3d; // value ? store int
- // value into
- // variable 2
- final static short istore_3 = 0x3e; // value ? store int
- // value into
- // variable 3
- final static short lstore_0 = 0x3f; // value ? store a long
- // value in
- // a local variable 0
- final static short dstore_3 = 0x4a; // value ? stores a
- // double into
- // local variable 3
- final static short astore_0 = 0x4b; // objectref ? stores a
- // reference into local variable
- // 0
- final static short astore_1 = 0x4c; // objectref ? stores a
- // reference into local variable
- // 1
- final static short astore_2 = 0x4d; // objectref ? stores a
- // reference into local variable
- // 2
- final static short astore_3 = 0x4e; // objectref ? stores a
- // reference into local variable
- // 3
- final static short iastore = 0x4f; // arrayref, index,
- // value ?
- // stores an int into an array
- final static short dup_x1 = 0x5a; // value2, value1 ?
- // value1,
- // value2, value1 inserts a copy
- // of the top value into the
- // stack two values from the top
- final static short dup_x2 = 0x5b; // value3, value2,
- // value1 ?
- // value1, value3, value2,
- // value1 inserts a copy of the
- // top value into the stack two
- // (if value2 is double or long
- // it takes up the entry of
- // value3, too) or three values
- // (if value2 is neither double
- // nor long) from the top
- final static short dup2 = 0x5c; // {value2, value1} ?
- // {value2,
- // value1}, {value2, value1}
- // duplicate top two stack words
- // (two values, if value1 is not
- // double nor long; a single
- // value, if value1 is double or
- // long)
- final static short dup2_x1 = 0x5d; // value3, {value2,
- // value1} ?
- // {value2, value1}, value3,
- // {value2, value1} duplicate
- // two words and insert beneath
- // third word (see explanation
- // above)
- final static short dup2_x2 = 0x5e; // {value4, value3},
- // {value2,
- // value1} ? {value2, value1},
- // {value4, value3}, {value2,
- // value1} duplicate two words
- // and insert beneath fourth
- // word
- final static short swap = 0x5f; // value2, value1 ?
- // value1,
- // value2 swaps two top words on
- // the stack (note that value1
- // and value2 must not be double
- // or long)
- final static short fmul = 0x6a; // value1, value2 ?
- // result
- // multiplies two floats
- final static short dmul = 0x6b; // value1, value2 ?
- // result
- // multiplies two doubles
- final static short idiv = 0x6c; // value1, value2 ?
- // result
- // divides two integers
- final static short ldiv = 0x6d; // value1, value2 ?
- // result
- // divide two longs
- final static short fdiv = 0x6e; // value1, value2 ?
- // result
- // divides two floats
- final static short ddiv = 0x6f; // value1, value2 ?
- // result
- // divides two doubles
- final static short ishr = 0x7a; // value1, value2 ?
- // result int
- // shift right
- final static short lshr = 0x7b; // value1, value2 ?
- // result
- // bitwise shift right of a long
- // value1 by value2 positions
- final static short iushr = 0x7c; // value1, value2 ?
- // result int
- // shift right
- final static short lushr = 0x7d; // value1, value2 ?
- // result
- // bitwise shift right of a long
- // value1 by value2 positions,
- // unsigned
- final static short iand = 0x7e; // value1, value2 ?
- // result
- // performs a logical and on two
- // integers
- final static short land = 0x7f; // value1, value2 ?
- // result
- // bitwise and of two longs
- final static short l2d = 0x8a; // value ? result
- // converts a
- // long to a double
- final static short f2i = 0x8b; // value ? result
- // converts a
- // float to an int
- final static short f2l = 0x8c; // value ? result
- // converts a
- // float to a long
- final static short f2d = 0x8d; // value ? result
- // converts a
- // float to a double
- final static short d2i = 0x8e; // value ? result
- // converts a
- // double to an int
- final static short d2l = 0x8f; // value ? result
- // converts a
- // double to a long
- final static short ifne = 0x9a; // branchbyte1,
- // branchbyte2
- // value ? if value is not 0,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short iflt = 0x9b; // branchbyte1,
- // branchbyte2
- // value ? if value is less than
- // 0, branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short ifge = 0x9c; // branchbyte1,
- // branchbyte2
- // value ? if value is greater
- // than or equal to 0, branch to
- // instruction at branchoffset
- // (signed short constructed
- // from unsigned bytes
- // branchbyte1 << 8 +
- // branchbyte2)
- final static short ifgt = 0x9d; // branchbyte1,
- // branchbyte2
- // value ? if value is greater
- // than 0, branch to instruction
- // at branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short ifle = 0x9e; // branchbyte1,
- // branchbyte2
- // value ? if value is less than
- // or equal to 0, branch to
- // instruction at branchoffset
- // (signed short constructed
- // from unsigned bytes
- // branchbyte1 << 8 +
- // branchbyte2)
- final static short if_icmpeq = 0x9f; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if ints are
- // equal, branch to instruction
- // at branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short if_icmpne = 0xa0; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if ints are
- // not equal, branch to
- // instruction at branchoffset
- // (signed short constructed
- // from unsigned bytes
- // branchbyte1 << 8 +
- // branchbyte2)
- final static short if_icmplt = 0xa1; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if value1 is
- // less than value2, branch to
- // instruction at branchoffset
- // (signed short constructed
- // from unsigned bytes
- // branchbyte1 << 8 +
- // branchbyte2)
- final static short if_icmpge = 0xa2; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if value1 is
- // greater than or equal to
- // value2, branch to instruction
- // at branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short if_icmpgt = 0xa3; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if value1 is
- // greater than value2, branch
- // to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short if_icmple = 0xa4; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if value1 is
- // less than or equal to value2,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short if_acmpeq = 0xa5; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if
- // references are equal, branch
- // to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short if_acmpne = 0xa6; // branchbyte1,
- // branchbyte2
- // value1, value2 ? if
- // references are not equal,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short goto_ = 0xa7; // branchbyte1,
- // branchbyte2 [no
- // change] goes to another
- // instruction at branchoffset
- // (signed short constructed
- // from unsigned bytes
- // branchbyte1 << 8 +
- // branchbyte2)
- final static short jsr = 0xa8; // branchbyte1,
- // branchbyte2 ?
- // address jump to subroutine at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2) and place the
- // return address on the stack
- final static short ret = 0xa9; // index [No change]
- // continue
- // execution from address taken
- // from a local variable #index
- // (the asymmetry with jsr is
- // intentional)
- final static short tableswitch = 0xaa; // [0-3 bytes padding],
- // defaultbyte1, defaultbyte2,
- // defaultbyte3, defaultbyte4,
- // lowbyte1, lowbyte2, lowbyte3,
- // lowbyte4, highbyte1,
- // highbyte2, highbyte3,
- // highbyte4, jump offsets...
- // index ? continue execution
- // from an address in the table
- // at offset index
- final static short lookupswitch = 0xab; // <0-3 bytes padding>,
- // defaultbyte1, defaultbyte2,
- // defaultbyte3, defaultbyte4,
- // npairs1, npairs2, npairs3,
- // npairs4, match-offset
- // pairs... key ? a target
- // address is looked up from a
- // table using a key and
- // execution continues from the
- // instruction at that address
- final static short ireturn = 0xac; // value ? [empty]
- // returns an
- // integer from a method
- final static short lreturn = 0xad; // value ? [empty]
- // returns a
- // long value
- final static short freturn = 0xae; // value ? [empty]
- // returns a
- // float
- final static short dreturn = 0xaf; // value ? [empty]
- // returns a
- // double from a method
- final static short areturn = 0xb0; // objectref ? [empty]
- // returns a
- // reference from a method
- final static short return_ = 0xb1; // ? [empty] return void
- // from
- // method
- final static short getstatic = 0xb2; // index1, index2 ?
- // value gets a
- // static field value of a
- // class, where the field is
- // identified by field reference
- // in the constant pool index
- // (index1 << 8 + index2)
- final static short putstatic = 0xb3; // indexbyte1,
- // indexbyte2 value
- // ? set static field to value
- // in a class, where the field
- // is identified by a field
- // reference index in constant
- // pool (indexbyte1 << 8 +
- // indexbyte2)
- final static short getfield = 0xb4; // index1, index2
- // objectref ?
- // value gets a field value of
- // an object objectref, where
- // the field is identified by
- // field reference in the
- // constant pool index (index1
- // << 8 + index2)
- final static short putfield = 0xb5; // indexbyte1,
- // indexbyte2
- // objectref, value ? set field
- // to value in an object
- // objectref, where the field is
- // identified by a field
- // reference index in constant
- // pool (indexbyte1 << 8 +
- // indexbyte2)
- final static short invokevirtual = 0xb6; // indexbyte1,
- // indexbyte2
- // objectref, [arg1, arg2, ...]
- // ? invoke virtual method on
- // object objectref, where the
- // method is identified by
- // method reference index in
- // constant pool (indexbyte1 <<
- // 8 + indexbyte2)
- final static short invokespecial = 0xb7; // indexbyte1,
- // indexbyte2
- // objectref, [arg1, arg2, ...]
- // ? invoke instance method on
- // object objectref, where the
- // method is identified by
- // method reference index in
- // constant pool (indexbyte1 <<
- // 8 + indexbyte2)
- final static short invokestatic = 0xb8; // indexbyte1,
- // indexbyte2 [arg1,
- // arg2, ...] ? invoke a static
- // method, where the method is
- // identified by method
- // reference index in constant
- // pool (indexbyte1 << 8 +
- // indexbyte2)
- final static short invokeinterface = 0xb9; // indexbyte1,
- // indexbyte2,
- // count, 0 objectref, [arg1,
- // arg2, ...] ? invokes an
- // interface method on object
- // objectref, where the
- // interface method is
- // identified by method
- // reference index in constant
- // pool (indexbyte1 << 8 +
- // indexbyte2)
- final static short xxxunusedxxx = 0xba; // this opcode is
- // reserved "for
- // historical reasons"
- final static short new_ = 0xbb; // indexbyte1,
- // indexbyte2 ?
- // objectref creates new object
- // of type identified by class
- // reference in constant pool
- // index (indexbyte1 << 8 +
- // indexbyte2)
- final static short newarray = 0xbc; // atype count ?
- // arrayref
- // creates new array with count
- // elements of primitive type
- // identified by atype
- final static short anewarray = 0xbd; // indexbyte1,
- // indexbyte2 count
- // ? arrayref creates a new
- // array of references of length
- // count and component type
- // identified by the class
- // reference index (indexbyte1
- // << 8 + indexbyte2) in the
- // constant pool
- final static short arraylength = 0xbe; // arrayref ? length
- // gets the
- // length of an array
- final static short athrow = 0xbf; // objectref ? [empty],
- // objectref throws an error or
- // exception (notice that the
- // rest of the stack is cleared,
- // leaving only a reference to
- // the Throwable)
- final static short checkcast = 0xc0; // indexbyte1,
- // indexbyte2
- // objectref ? objectref checks
- // whether an objectref is of a
- // certain type, the class
- // reference of which is in the
- // constant pool at index
- // (indexbyte1 << 8 +
- // indexbyte2)
- final static short instanceof_ = 0xc1; // indexbyte1,
- // indexbyte2
- // objectref ? result determines
- // if an object objectref is of
- // a given type, identified by
- // class reference index in
- // constant pool (indexbyte1 <<
- // 8 + indexbyte2)
- final static short monitorenter = 0xc2; // objectref ? enter
- // monitor for
- // object ("grab the lock" -
- // start of synchronized()
- // section)
- final static short monitorexit = 0xc3; // objectref ? exit
- // monitor for
- // object ("release the lock" -
- // end of synchronized()
- // section)
- final static short wide = 0xc4; // opcode, indexbyte1,
- // indexbyte2
- final static short multianewarray = 0xc5; // indexbyte1,
- // indexbyte2,
- // dimensions count1,
- // [count2,...] ? arrayref
- // create a new array of
- // dimensions dimensions with
- // elements of type identified
- // by class reference in
- // constant pool index
- // (indexbyte1 << 8 +
- // indexbyte2); the sizes of
- // each dimension is identified
- // by count1, [count2, etc]
- final static short ifnull = 0xc6; // branchbyte1,
- // branchbyte2
- // value ? if value is null,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short ifnonnull = 0xc7; // branchbyte1,
- // branchbyte2
- // value ? if value is not null,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned
- // bytes branchbyte1 << 8 +
- // branchbyte2)
- final static short goto_w = 0xc8; // branchbyte1,
- // branchbyte2,
- // branchbyte3, branchbyte4 [no
- // change] goes to another
- // instruction at branchoffset
- // (signed int constructed from
- // unsigned bytes branchbyte1 <<
- // 24 + branchbyte2 << 16 +
- // branchbyte3 << 8 +
- // branchbyte4)
- final static short jsr_w = 0xc9; // branchbyte1,
- // branchbyte2,
- // branchbyte3, branchbyte4 ?
- // address jump to subroutine at
- // branchoffset (signed int
- // constructed from unsigned
- // bytes branchbyte1 << 24 +
- // branchbyte2 << 16 +
- // branchbyte3 << 8 +
- // branchbyte4) and place the
- // return address on the stack
- final static short breakpoint = 0xca; // reserved for
- // breakpoints in
- // Java debuggers; should not
- // appear in any class file
- final static short impdep1 = 0xfe; // reserved for
- // implementation-dependent
- // operations within debuggers;
- // should not appear in any
- // class file
- final static short impdep2 = 0xff; // reserved for
- // implementation-dependent
- // operations within debuggers;
- // should not appear in any
- // class file
-
- final static byte OFFSETS[] = new byte[256];
-
- static {
- OFFSETS[bipush] = 1; // byte ? value pushes a byte onto the
- // stack as an integer value
- OFFSETS[sipush] = 2; // byte1, byte2 ? value pushes a signed
- // integer (byte1 << 8 + byte2) onto the
- // stack
- OFFSETS[ldc] = 1; // index ? value pushes a constant
- // #index from a constant pool (String,
- // int, float or class type) onto the
- // stack
- OFFSETS[ldc_w] = 2; // indexbyte1, indexbyte2 ? value pushes
- // a constant #index from a constant
- // pool (String, int, float or class
- // type) onto the stack (wide index is
- // constructed as indexbyte1 << 8 +
- // indexbyte2)
- OFFSETS[ldc2_w] = 2; // indexbyte1, indexbyte2 ? value pushes
- // a constant #index from a constant
- // pool (double or long) onto the stack
- // (wide index is constructed as
- // indexbyte1 << 8 + indexbyte2)
- OFFSETS[iload] = 1; // index ? value loads an int value from
- // a variable #index
- OFFSETS[lload] = 1; // index ? value load a long value from
- // a local variable #index
- OFFSETS[fload] = 1; // index ? value loads a float value
- // from a local variable #index
- OFFSETS[dload] = 1; // index ? value loads a double value
- // from a local variable #index
- OFFSETS[aload] = 1; // index ? objectref loads a reference
- // onto the stack from a local variable
- // #index
- OFFSETS[istore] = 1; // index value ? store int value into
- // variable #index
- OFFSETS[lstore] = 1; // index value ? store a long value in a
- // local variable #index
- OFFSETS[fstore] = 1; // index value ? stores a float value
- // into a local variable #index
- OFFSETS[dstore] = 1; // index value ? stores a double value
- // into a local variable #index
- OFFSETS[iinc] = 2; // index, const [No change] increment
- // local variable #index by signed byte
- // const
- OFFSETS[ifeq] = 2; // branchbyte1, branchbyte2 value ? if
- // value is 0, branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[astore] = 1; // index objectref ? stores a reference
- // into a local variable #index
- OFFSETS[ifne] = 2; // branchbyte1, branchbyte2 value ? if
- // value is not 0, branch to instruction
- // at branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[iflt] = 2; // branchbyte1, branchbyte2 value ? if
- // value is less than 0, branch to
- // instruction at branchoffset (signed
- // short constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[ifge] = 2; // branchbyte1, branchbyte2 value ? if
- // value is greater than or equal to 0,
- // branch to instruction at branchoffset
- // (signed short constructed from
- // unsigned bytes branchbyte1 << 8 +
- // branchbyte2)
- OFFSETS[ifgt] = 2; // branchbyte1, branchbyte2 value ? if
- // value is greater than 0, branch to
- // instruction at branchoffset (signed
- // short constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[ifle] = 2; // branchbyte1, branchbyte2 value ? if
- // value is less than or equal to 0,
- // branch to instruction at branchoffset
- // (signed short constructed from
- // unsigned bytes branchbyte1 << 8 +
- // branchbyte2)
- OFFSETS[if_icmpeq] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if ints are equal,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[if_icmpne] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if ints are not equal,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[if_icmplt] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if value1 is less than
- // value2, branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[if_icmpge] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if value1 is greater
- // than or equal to value2, branch
- // to instruction at branchoffset
- // (signed short constructed from
- // unsigned bytes branchbyte1 << 8 +
- // branchbyte2)
- OFFSETS[if_icmpgt] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if value1 is greater
- // than value2, branch to
- // instruction at branchoffset
- // (signed short constructed from
- // unsigned bytes branchbyte1 << 8 +
- // branchbyte2)
- OFFSETS[if_icmple] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if value1 is less than
- // or equal to value2, branch to
- // instruction at branchoffset
- // (signed short constructed from
- // unsigned bytes branchbyte1 << 8 +
- // branchbyte2)
- OFFSETS[if_acmpeq] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if references are equal,
- // branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[if_acmpne] = 2; // branchbyte1, branchbyte2 value1,
- // value2 ? if references are not
- // equal, branch to instruction at
- // branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[goto_] = 2; // branchbyte1, branchbyte2 [no change]
- // goes to another instruction at
- // branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[jsr] = 2; // branchbyte1, branchbyte2 ? address
- // jump to subroutine at branchoffset
- // (signed short constructed from
- // unsigned bytes branchbyte1 << 8 +
- // branchbyte2) and place the return
- // address on the stack
- OFFSETS[ret] = 1; // index [No change] continue execution
- // from address taken from a local
- // variable #index (the asymmetry with
- // jsr is intentional)
- OFFSETS[tableswitch] = -1; // [0-3 bytes padding],
- // defaultbyte1, defaultbyte2,
- // defaultbyte3, defaultbyte4,
- // lowbyte1, lowbyte2, lowbyte3,
- // lowbyte4, highbyte1,
- // highbyte2, highbyte3,
- // highbyte4, jump offsets...
- // index ? continue execution
- // from an address in the table
- // at offset index
- OFFSETS[lookupswitch] = -1; // <0-3 bytes padding>,
- // defaultbyte1, defaultbyte2,
- // defaultbyte3, defaultbyte4,
- // npairs1, npairs2, npairs3,
- // npairs4, match-offset
- // pairs... key ? a target
- // address is looked up from a
- // table using a key and
- // execution continues from the
- // instruction at that address
- OFFSETS[getstatic] = 2; // index1, index2 ? value gets a
- // static field value of a class,
- // where the field is identified by
- // field reference in the constant
- // pool index (index1 << 8 + index2)
- OFFSETS[putstatic] = 2; // indexbyte1, indexbyte2 value ?
- // set static field to value in a
- // class, where the field is
- // identified by a field reference
- // index in constant pool
- // (indexbyte1 << 8 + indexbyte2)
- OFFSETS[getfield] = 2; // index1, index2 objectref ? value
- // gets a field value of an object
- // objectref, where the field is
- // identified by field reference in
- // the constant pool index (index1
- // << 8 + index2)
- OFFSETS[putfield] = 2; // indexbyte1, indexbyte2 objectref,
- // value ? set field to value in an
- // object objectref, where the field
- // is identified by a field
- // reference index in constant pool
- // (indexbyte1 << 8 + indexbyte2)
- OFFSETS[invokevirtual] = 2; // indexbyte1, indexbyte2
- // objectref, [arg1, arg2, ...]
- // ? invoke virtual method on
- // object objectref, where the
- // method is identified by
- // method reference index in
- // constant pool (indexbyte1 <<
- // 8 + indexbyte2)
- OFFSETS[invokespecial] = 2; // indexbyte1, indexbyte2
- // objectref, [arg1, arg2, ...]
- // ? invoke instance method on
- // object objectref, where the
- // method is identified by
- // method reference index in
- // constant pool (indexbyte1 <<
- // 8 + indexbyte2)
- OFFSETS[invokestatic] = 2; // indexbyte1, indexbyte2 [arg1,
- // arg2, ...] ? invoke a static
- // method, where the method is
- // identified by method
- // reference index in constant
- // pool (indexbyte1 << 8 +
- // indexbyte2)
- OFFSETS[invokeinterface] = 2; // indexbyte1, indexbyte2,
- // count, 0 objectref,
- // [arg1, arg2, ...] ?
- // invokes an interface
- // method on object
- // objectref, where the
- // interface method is
- // identified by method
- // reference index in
- // constant pool (indexbyte1
- // << 8 + indexbyte2)
- OFFSETS[new_] = 2; // indexbyte1, indexbyte2 ? objectref
- // creates new object of type identified
- // by class reference in constant pool
- // index (indexbyte1 << 8 + indexbyte2)
- OFFSETS[newarray] = 1; // atype count ? arrayref creates
- // new array with count elements of
- // primitive type identified by
- // atype
- OFFSETS[anewarray] = 2; // indexbyte1, indexbyte2 count ?
- // arrayref creates a new array of
- // references of length count and
- // component type identified by the
- // class reference index (indexbyte1
- // << 8 + indexbyte2) in the
- // constant pool
- OFFSETS[checkcast] = 2; // indexbyte1, indexbyte2 objectref
- // ? objectref checks whether an
- // objectref is of a certain type,
- // the class reference of which is
- // in the constant pool at index
- // (indexbyte1 << 8 + indexbyte2)
- OFFSETS[instanceof_] = 2; // indexbyte1, indexbyte2 objectref
- // ? result determines if an object
- // objectref is of a given type,
- // identified by class reference
- // index in constant pool
- // (indexbyte1 << 8 + indexbyte2)
- OFFSETS[wide] = 3; // opcode, indexbyte1, indexbyte2
- OFFSETS[multianewarray] = 3; // indexbyte1, indexbyte2,
- // dimensions count1,
- // [count2,...] ? arrayref
- // create a new array of
- // dimensions dimensions with
- // elements of type identified
- // by class reference in
- // constant pool index
- // (indexbyte1 << 8 +
- // indexbyte2); the sizes of
- // each dimension is identified
- // by count1, [count2, etc]
- OFFSETS[ifnull] = 2; // branchbyte1, branchbyte2 value ? if
- // value is null, branch to instruction
- // at branchoffset (signed short
- // constructed from unsigned bytes
- // branchbyte1 << 8 + branchbyte2)
- OFFSETS[ifnonnull] = 2; // branchbyte1, branchbyte2 value ?
- // if value is not null, branch to
- // instruction at branchoffset
- // (signed short constructed from
- // unsigned bytes branchbyte1 << 8 +
- // branchbyte2)
- OFFSETS[goto_w] = 4; // branchbyte1, branchbyte2,
- // branchbyte3, branchbyte4 [no change]
- // goes to another instruction at
- // branchoffset (signed int constructed
- // from unsigned bytes branchbyte1 << 24
- // + branchbyte2 << 16 + branchbyte3 <<
- // 8 + branchbyte4)
- OFFSETS[jsr_w] = 4; // branchbyte1, branchbyte2,
- // branchbyte3, branchbyte4 ? address
- // jump to subroutine at branchoffset
- // (signed int constructed from unsigned
- // bytes branchbyte1 << 24 + branchbyte2
- // << 16 + branchbyte3 << 8 +
- // branchbyte4) and place the return
- // address on the stack
- }
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/PreprocessResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/PreprocessResource.java
deleted file mode 100644
index 8299af8..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/PreprocessResource.java
+++ /dev/null
@@ -1,37 +0,0 @@
-package aQute.lib.osgi;
-
-import java.io.*;
-
-public class PreprocessResource extends AbstractResource {
- final Resource resource;
- final Processor processor;
-
- public PreprocessResource(Processor processor, Resource r) {
- super(r.lastModified());
- this.processor = processor;
- this.resource = r;
- extra = resource.getExtra();
- }
-
- protected byte[] getBytes() throws IOException {
- ByteArrayOutputStream bout = new ByteArrayOutputStream(2000);
- OutputStreamWriter osw = new OutputStreamWriter(bout);
- PrintWriter pw = new PrintWriter(osw);
- InputStream in = resource.openInputStream();
- try {
- BufferedReader rdr = new BufferedReader(new InputStreamReader(in));
- String line = rdr.readLine();
- while (line != null) {
- line = processor.getReplacer().process(line);
- pw.println(line);
- line = rdr.readLine();
- }
- pw.flush();
- byte [] data= bout.toByteArray();
- return data;
-
- } finally {
- in.close();
- }
- }
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java b/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
deleted file mode 100644
index 29da425..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Processor.java
+++ /dev/null
@@ -1,1005 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.net.*;
-import java.util.*;
-import java.util.jar.*;
-
-import aQute.bnd.make.*;
-import aQute.bnd.service.*;
-import aQute.libg.header.*;
-import aQute.libg.reporter.*;
-
-public class Processor implements Reporter, Constants, Closeable {
- // TODO handle include files out of date
- public static String DEFAULT_PLUGINS = ""; // "aQute.lib.spring.SpringComponent";
- // TODO make splitter skip eagerly whitespace so trim is not necessary
- public static String LIST_SPLITTER = "\\\\?\\s*,\\s*";
- private List<String> errors = new ArrayList<String>();
- private List<String> warnings = new ArrayList<String>();
- boolean pedantic;
- boolean trace;
- boolean exceptions;
- boolean fileMustExist = true;
-
- List<Object> plugins;
- private File base = new File("").getAbsoluteFile();
- private List<Closeable> toBeClosed = newList();
-
- final Properties properties;
- private Macro replacer;
- private long lastModified;
- private File propertiesFile;
- private boolean fixup = true;
- long modified;
- Processor parent;
- Set<File> included;
- CL pluginLoader;
-
- public Processor() {
- properties = new Properties();
- }
-
- public Processor(Properties parent) {
- properties = new Properties(parent);
- }
-
- public Processor(Processor parent) {
- this(parent.properties);
- this.parent = parent;
- }
-
- public void setParent(Processor processor) {
- this.parent = processor;
- }
-
- public Processor getParent() {
- return parent;
- }
-
- public void getInfo(Processor processor, String prefix) {
- if (isFailOk())
- addAll(warnings, processor.getErrors(), prefix);
- else
- addAll(errors, processor.getErrors(), prefix);
- addAll(warnings, processor.getWarnings(), prefix);
-
- processor.errors.clear();
- processor.warnings.clear();
- }
-
- public void getInfo(Processor processor) {
- getInfo(processor, "");
- }
-
- private <T> void addAll(List<String> to, List<? extends T> from,
- String prefix) {
- for (T x : from) {
- to.add(prefix + x);
- }
- }
-
- public void warning(String string, Object ...args) {
- String s = String.format(string,args);
- if ( ! warnings.contains(s))
- warnings.add(s);
- }
-
- public void error(String string, Object ...args) {
- if (isFailOk())
- warning(string, args);
- else {
- String s = String.format(string,args);
- if ( ! errors.contains(s))
- errors.add(s);
- }
- }
-
- public void error(String string, Throwable t, Object ... args) {
- if (isFailOk())
- warning(string + ": " + t, args);
- else{
- String s = String.format(string,args);
- if ( ! errors.contains(s))
- errors.add(s);
- }
- if (exceptions)
- t.printStackTrace();
- }
-
- public List<String> getWarnings() {
- return warnings;
- }
-
- public List<String> getErrors() {
- return errors;
- }
-
- public Map<String, Map<String, String>> parseHeader(String value) {
- return parseHeader(value, this);
- }
-
- /**
- * Standard OSGi header parser.
- *
- * @param value
- * @return
- */
- @SuppressWarnings("unchecked")
- static public Map<String, Map<String, String>> parseHeader(String value,
- Processor logger) {
- return OSGiHeader.parseHeader(value, logger);
- }
-
- Map<String, Map<String, String>> getClauses(String header) {
- return parseHeader(getProperty(header));
- }
-
- public void addClose(Closeable jar) {
- toBeClosed.add(jar);
- }
-
- /**
- * Remove all entries from a map that start with a specific prefix
- *
- * @param <T>
- * @param source
- * @param prefix
- * @return
- */
- static <T> Map<String, T> removeKeys(Map<String, T> source, String prefix) {
- Map<String, T> temp = new TreeMap<String, T>(source);
- for (Iterator<String> p = temp.keySet().iterator(); p.hasNext();) {
- String pack = (String) p.next();
- if (pack.startsWith(prefix))
- p.remove();
- }
- return temp;
- }
-
- public void progress(String s, Object ... args) {
- // System.out.println(s);
- }
-
- public boolean isPedantic() {
- return pedantic;
- }
-
- public void setPedantic(boolean pedantic) { // System.out.println("Set
- // pedantic: " + pedantic + " "
- // + this );
- this.pedantic = pedantic;
- }
-
- public static File getFile(File base, String file) {
- File f = new File(file);
- if (f.isAbsolute())
- return f;
- int n;
-
- f = base.getAbsoluteFile();
- while ((n = file.indexOf('/')) > 0) {
- String first = file.substring(0, n);
- file = file.substring(n + 1);
- if (first.equals(".."))
- f = f.getParentFile();
- else
- f = new File(f, first);
- }
- return new File(f, file).getAbsoluteFile();
- }
-
- public File getFile(String file) {
- return getFile(base, file);
- }
-
- /**
- * Return a list of plugins that implement the given class.
- *
- * @param clazz
- * Each returned plugin implements this class/interface
- * @return A list of plugins
- */
- public <T> List<T> getPlugins(Class<T> clazz) {
- List<T> l = new ArrayList<T>();
- List<Object> all = getPlugins();
- for (Object plugin : all) {
- if (clazz.isInstance(plugin))
- l.add(clazz.cast(plugin));
- }
- return l;
- }
-
- /**
- * Return a list of plugins. Plugins are defined with the -plugin command.
- * They are class names, optionally associated with attributes. Plugins can
- * implement the Plugin interface to see these attributes.
- *
- * Any object can be a plugin.
- *
- * @return
- */
- protected List<Object> getPlugins() {
- if ( parent != null )
- return parent.getPlugins();
-
- if (this.plugins != null)
- return this.plugins;
-
- String spe = getProperty(Analyzer.PLUGIN, DEFAULT_PLUGINS);
- Map<String, Map<String, String>> plugins = parseHeader(spe);
- List<Object> list = new ArrayList<Object>();
-
- // Add the default plugins. Only if non is specified
- // will they be removed.
- list.add(new MakeBnd());
- list.add(new MakeCopy());
-
- for (Map.Entry<String, Map<String, String>> entry : plugins.entrySet()) {
- String key = (String) entry.getKey();
- if (key.equals("none"))
- return this.plugins = newList();
-
- try {
- CL loader = getLoader();
- String path = entry.getValue().get("path:");
- if ( path != null ) {
- File f = getFile(path).getAbsoluteFile();
- loader.add(f.toURL());
- }
-
- trace("Using plugin %s", key);
-
- // Plugins could use the same class with different
- // parameters so we could have duplicate names Remove
- // the ! added by the parser to make each name unique.
- key = removeDuplicateMarker(key);
-
- Class<?> c = (Class<?>) loader.loadClass(
- key);
- Object plugin = c.newInstance();
- if (plugin instanceof Plugin) {
- ((Plugin) plugin).setProperties(entry.getValue());
- ((Plugin) plugin).setReporter(this);
- }
- list.add(plugin);
- } catch (Exception e) {
- error("Problem loading the plugin: " + key + " exception: " + e);
- }
- }
- return this.plugins = list;
- }
-
- public boolean isFailOk() {
- String v = getProperty(Analyzer.FAIL_OK, null);
- return v != null && v.equalsIgnoreCase("true");
- }
-
- public File getBase() {
- return base;
- }
-
- public void setBase(File base) {
- this.base = base;
- }
-
- public void clear() {
- errors.clear();
- warnings.clear();
- }
-
- public void trace(String msg, Object... parms) {
- if (trace) {
- System.out.printf("# " + msg + "\n", parms);
- }
- }
-
- public <T> List<T> newList() {
- return new ArrayList<T>();
- }
-
- public <T> Set<T> newSet() {
- return new TreeSet<T>();
- }
-
- public static <K, V> Map<K, V> newMap() {
- return new LinkedHashMap<K, V>();
- }
-
- public static <K, V> Map<K, V> newHashMap() {
- return new HashMap<K, V>();
- }
-
- public <T> List<T> newList(Collection<T> t) {
- return new ArrayList<T>(t);
- }
-
- public <T> Set<T> newSet(Collection<T> t) {
- return new TreeSet<T>(t);
- }
-
- public <K, V> Map<K, V> newMap(Map<K, V> t) {
- return new LinkedHashMap<K, V>(t);
- }
-
- public void close() {
- for (Closeable c : toBeClosed) {
- try {
- c.close();
- } catch (IOException e) {
- // Who cares?
- }
- }
- toBeClosed = null;
- }
-
- public String _basedir(String args[]) {
- if (base == null)
- throw new IllegalArgumentException("No base dir set");
-
- return base.getAbsolutePath();
- }
-
- /**
- * Property handling ...
- *
- * @return
- */
-
- public Properties getProperties() {
- if (fixup) {
- fixup = false;
- begin();
- }
-
- return properties;
- }
-
- public String getProperty(String key) {
- return getProperty(key, null);
- }
-
- public void mergeProperties(File file, boolean override) {
- if (file.isFile()) {
- try {
- Properties properties = loadProperties(file);
- mergeProperties(properties, override);
- } catch (Exception e) {
- error("Error loading properties file: " + file);
- }
- } else {
- if (!file.exists())
- error("Properties file does not exist: " + file);
- else
- error("Properties file must a file, not a directory: " + file);
- }
- }
-
- public void mergeProperties(Properties properties, boolean override) {
- for (Enumeration<?> e = properties.propertyNames(); e.hasMoreElements();) {
- String key = (String) e.nextElement();
- String value = properties.getProperty(key);
- if (override || !getProperties().containsKey(key))
- setProperty(key, value);
- }
- }
-
- public void setProperties(Properties properties) {
- doIncludes(getBase(), properties, new HashSet<String>());
- this.properties.putAll(properties);
- }
-
- public void addProperties(File file) throws Exception {
- addIncluded(file);
- Properties p = loadProperties(file);
- setProperties(p);
- }
-
- public synchronized void addIncluded(File file) {
- if (included == null)
- included = new HashSet<File>();
- included.add(file);
- }
-
- /**
- * Inspect the properties and if you find -includes parse the line included
- * manifest files or properties files. The files are relative from the given
- * base, this is normally the base for the analyzer.
- *
- * @param ubase
- * @param p
- * @param done
- * @throws IOException
- */
- private void doIncludes(File ubase, Properties p, Set<String> done) {
- String includes = p.getProperty(INCLUDE);
- if (includes != null) {
- includes = getReplacer().process(includes);
- p.remove(INCLUDE);
- Collection<String> clauses = parseHeader(includes).keySet();
-
- for (String value : clauses) {
- boolean fileMustExist = true;
- boolean overwrite = true;
- while (true) {
- if (value.startsWith("-")) {
- fileMustExist = false;
- value = value.substring(1).trim();
- } else if (value.startsWith("~")) {
- // Overwrite properties!
- overwrite = false;
- value = value.substring(1).trim();
- } else
- break;
- }
- try {
- File file = getFile(ubase, value).getAbsoluteFile();
- if (file.isFile()) {
- if (included != null && included.contains(file)) {
- error("Cyclic include of " + file);
- } else {
- addIncluded(file);
- updateModified(file.lastModified(), "Include "
- + value);
- InputStream in = new FileInputStream(file);
- Properties sub;
- if (file.getName().toLowerCase().endsWith(".mf")) {
- sub = getManifestAsProperties(in);
- } else
- sub = loadProperties(in, file.getAbsolutePath());
- in.close();
-
- doIncludes(file.getParentFile(), sub, done);
- // make sure we do not override properties
- if (!overwrite)
- sub.keySet().removeAll(p.keySet());
- p.putAll(sub);
- }
- } else {
- if (fileMustExist)
- error("Included file "
- + file
- + (file.exists() ? " does not exist"
- : " is directory"));
- }
- } catch (IOException e) {
- if (fileMustExist)
- error("Error in processing included file: " + value, e);
- }
- }
- }
- }
-
- public void unsetProperty(String string) {
- getProperties().remove(string);
-
- }
-
- public boolean refresh() {
- if (propertiesFile == null)
- return false;
-
- boolean changed = false;
- if (included != null) {
- for (File file : included) {
-
- if (file.lastModified() > modified) {
- changed = true;
- break;
- }
- }
- }
-
- // System.out.println("Modified " + modified + " file: "
- // + propertiesFile.lastModified() + " diff "
- // + (modified - propertiesFile.lastModified()));
-
- //Date last = new Date(propertiesFile.lastModified());
- //Date current = new Date(modified);
- changed |= modified < propertiesFile.lastModified();
- if (changed) {
- included = null;
- properties.clear();
- plugins = null;
- setProperties(propertiesFile, base);
- propertiesChanged();
- return true;
- }
- return false;
- }
-
- public void propertiesChanged() {
- }
-
- /**
- * Set the properties by file. Setting the properties this way will also set
- * the base for this analyzer. After reading the properties, this will call
- * setProperties(Properties) which will handle the includes.
- *
- * @param propertiesFile
- * @throws FileNotFoundException
- * @throws IOException
- */
- public void setProperties(File propertiesFile) throws IOException {
- propertiesFile = propertiesFile.getAbsoluteFile();
- setProperties(propertiesFile, propertiesFile.getParentFile());
- }
-
- public void setProperties(File propertiesFile, File base) {
- this.propertiesFile = propertiesFile.getAbsoluteFile();
- setBase(base);
- try {
- if (propertiesFile.isFile()) {
- // System.out.println("Loading properties " + propertiesFile);
- long modified = propertiesFile.lastModified();
- if ( modified > System.currentTimeMillis() +100) {
- System.out.println("Huh? This is in the future " + propertiesFile );
- this.modified = System.currentTimeMillis();
- } else
- this.modified = modified;
-
- included = null;
- Properties p = loadProperties(propertiesFile);
- setProperties(p);
- } else {
- if (fileMustExist) {
- error("No such properties file: " + propertiesFile);
- }
- }
- } catch (IOException e) {
- error("Could not load properties " + propertiesFile);
- }
- }
-
- protected void begin() {
- if (isTrue(getProperty(PEDANTIC)))
- setPedantic(true);
- }
-
- public static boolean isTrue(String value) {
- return "true".equalsIgnoreCase(value);
- }
-
- /**
- * Get a property with a proper default
- *
- * @param headerName
- * @param deflt
- * @return
- */
- public String getProperty(String key, String deflt) {
- String value = getProperties().getProperty(key);
- if (value != null)
- return getReplacer().process(value);
- else if (deflt != null)
- return getReplacer().process(deflt);
- else
- return null;
- }
-
- /**
- * Helper to load a properties file from disk.
- *
- * @param file
- * @return
- * @throws IOException
- */
- public Properties loadProperties(File file) throws IOException {
- updateModified(file.lastModified(), "Properties file: " + file);
- InputStream in = new FileInputStream(file);
- Properties p = loadProperties(in, file.getAbsolutePath());
- in.close();
- return p;
- }
-
- Properties loadProperties(InputStream in, String name) throws IOException {
- int n = name.lastIndexOf('/');
- if (n > 0)
- name = name.substring(0, n);
- if (name.length() == 0)
- name = ".";
-
- try {
- Properties p = new Properties();
- p.load(in);
- return replaceAll(p, "\\$\\{\\.\\}", name);
- } catch (Exception e) {
- error("Error during loading properties file: " + name + ", error:"
- + e);
- return new Properties();
- }
- }
-
- /**
- * Replace a string in all the values of the map. This can be used to
- * preassign variables that change. I.e. the base directory ${.} for a
- * loaded properties
- */
-
- public static Properties replaceAll(Properties p, String pattern,
- String replacement) {
- Properties result = new Properties();
- for (Iterator<Map.Entry<Object, Object>> i = p.entrySet().iterator(); i
- .hasNext();) {
- Map.Entry<Object, Object> entry = i.next();
- String key = (String) entry.getKey();
- String value = (String) entry.getValue();
- value = value.replaceAll(pattern, replacement);
- result.put(key, value);
- }
- return result;
- }
-
- /**
- * Merge the attributes of two maps, where the first map can contain
- * wildcarded names. The idea is that the first map contains patterns (for
- * example *) with a set of attributes. These patterns are matched against
- * the found packages in actual. If they match, the result is set with the
- * merged set of attributes. It is expected that the instructions are
- * ordered so that the instructor can define which pattern matches first.
- * Attributes in the instructions override any attributes from the actual.<br/>
- *
- * A pattern is a modified regexp so it looks like globbing. The * becomes a .*
- * just like the ? becomes a .?. '.' are replaced with \\. Additionally, if
- * the pattern starts with an exclamation mark, it will remove that matches
- * for that pattern (- the !) from the working set. So the following
- * patterns should work:
- * <ul>
- * <li>com.foo.bar</li>
- * <li>com.foo.*</li>
- * <li>com.foo.???</li>
- * <li>com.*.[^b][^a][^r]</li>
- * <li>!com.foo.* (throws away any match for com.foo.*)</li>
- * </ul>
- * Enough rope to hang the average developer I would say.
- *
- *
- * @param instructions
- * the instructions with patterns. A
- * @param actual
- * the actual found packages
- */
-
- public static Map<String, Map<String, String>> merge(String type,
- Map<String, Map<String, String>> instructions,
- Map<String, Map<String, String>> actual,
- Set<String> superfluous,
- Map<String, Map<String,String>> ignored) {
- Map<String, Map<String, String>> toVisit = new HashMap<String, Map<String, String>>(
- actual); // we do not want to ruin our
- // original
- Map<String, Map<String, String>> result = newMap();
- for (Iterator<String> i = instructions.keySet().iterator(); i.hasNext();) {
- String instruction = i.next();
- String originalInstruction = instruction;
-
- Map<String, String> instructedAttributes = instructions
- .get(instruction);
-
- // Check if we have a fixed (starts with '=') or a
- // duplicate name. A fixed name is added to the output without
- // checking against the contents. Duplicates are marked
- // at the end. In that case we do not pick up any contained
- // information but just add them to the output including the
- // marker.
- if (instruction.startsWith("=")) {
- result.put(instruction.substring(1), instructedAttributes);
- superfluous.remove(originalInstruction);
- continue;
- }
- if (isDuplicate(instruction)) {
- result.put(instruction, instructedAttributes);
- superfluous.remove(originalInstruction);
- continue;
- }
-
- Instruction instr = Instruction.getPattern(instruction);
-
- for (Iterator<String> p = toVisit.keySet().iterator(); p.hasNext();) {
- String packageName = p.next();
-
- if (instr.matches(packageName)) {
- superfluous.remove(originalInstruction);
- if (!instr.isNegated()) {
- Map<String, String> newAttributes = new HashMap<String, String>();
- newAttributes.putAll(actual.get(packageName));
- newAttributes.putAll(instructedAttributes);
- result.put(packageName, newAttributes);
- } else if (ignored != null) {
- ignored.put(packageName, new HashMap<String, String>());
- }
- p.remove(); // Can never match again for another pattern
- }
- }
-
- }
- return result;
- }
-
- /**
- * Print a standard Map based OSGi header.
- *
- * @param exports
- * map { name => Map { attribute|directive => value } }
- * @return the clauses
- */
- public static String printClauses(Map<String, Map<String, String>> exports,
- String allowedDirectives) {
- return printClauses(exports, allowedDirectives, false);
- }
-
- public static String printClauses(Map<String, Map<String, String>> exports,
- String allowedDirectives, boolean checkMultipleVersions) {
- StringBuffer sb = new StringBuffer();
- String del = "";
- for (Iterator<String> i = exports.keySet().iterator(); i.hasNext();) {
- String name = i.next();
- Map<String, String> clause = exports.get(name);
-
- // We allow names to be duplicated in the input
- // by ending them with '~'. This is necessary to use
- // the package names as keys. However, we remove these
- // suffixes in the output so that you can set multiple
- // exports with different attributes.
- String outname = removeDuplicateMarker(name);
- sb.append(del);
- sb.append(outname);
- printClause(clause, allowedDirectives, sb);
- del = ",";
- }
- return sb.toString();
- }
-
- public static void printClause(Map<String, String> map,
- String allowedDirectives, StringBuffer sb) {
-
- for (Iterator<String> j = map.keySet().iterator(); j.hasNext();) {
- String key = j.next();
-
- // Skip directives we do not recognize
- if (!key.startsWith("x-")
- && key.endsWith(":")
- && (allowedDirectives == null || allowedDirectives
- .indexOf(key) < 0))
- continue;
-
- String value = ((String) map.get(key)).trim();
- sb.append(";");
- sb.append(key);
- sb.append("=");
-
- boolean clean = (value.length() >= 2 && value.charAt(0) == '"' && value
- .charAt(value.length() - 1) == '"')
- || Verifier.TOKEN.matcher(value).matches();
- if (!clean)
- sb.append("\"");
- sb.append(value);
- if (!clean)
- sb.append("\"");
- }
- }
-
- public Macro getReplacer() {
- if (replacer == null)
- return replacer = new Macro(getProperties(), this,
- getMacroDomains());
- else
- return replacer;
- }
-
- /**
- * This should be overridden by subclasses to add extra macro command
- * domains on the search list.
- *
- * @return
- */
- protected Object[] getMacroDomains() {
- return new Object[] {};
- }
-
- /**
- * Return the properties but expand all macros. This always returns a new
- * Properties object that can be used in any way.
- *
- * @return
- */
- public Properties getFlattenedProperties() {
- return getReplacer().getFlattenedProperties();
-
- }
-
- public void updateModified(long time, String reason) {
- if (time > lastModified) {
- lastModified = time;
- }
- }
-
- public long lastModified() {
- return lastModified;
- }
-
- /**
- * Add or override a new property.
- *
- * @param key
- * @param value
- */
- public void setProperty(String key, String value) {
- checkheader: for (int i = 0; i < headers.length; i++) {
- if (headers[i].equalsIgnoreCase(value)) {
- value = headers[i];
- break checkheader;
- }
- }
- getProperties().put(key, value);
- }
-
- /**
- * Read a manifest but return a properties object.
- *
- * @param in
- * @return
- * @throws IOException
- */
- public static Properties getManifestAsProperties(InputStream in)
- throws IOException {
- Properties p = new Properties();
- Manifest manifest = new Manifest(in);
- for (Iterator<Object> it = manifest.getMainAttributes().keySet()
- .iterator(); it.hasNext();) {
- Attributes.Name key = (Attributes.Name) it.next();
- String value = manifest.getMainAttributes().getValue(key);
- p.put(key.toString(), value);
- }
- return p;
- }
-
- public File getPropertiesFile() {
- return propertiesFile;
- }
-
- public void setFileMustExist(boolean mustexist) {
- fileMustExist = mustexist;
- }
-
- static public String read(InputStream in) throws Exception {
- InputStreamReader ir = new InputStreamReader(in);
- StringBuilder sb = new StringBuilder();
-
- try {
- char chars[] = new char[1000];
- int size = ir.read(chars);
- while (size > 0) {
- sb.append(chars, 0, size);
- size = ir.read(chars);
- }
- } finally {
- ir.close();
- }
- return sb.toString();
- }
-
- /**
- * Join a list.
- *
- * @param args
- * @return
- */
- public static String join(Collection<?> list, String delimeter) {
- if ( list == null )
- return "";
- StringBuilder sb = new StringBuilder();
- String del = "";
- for (Object item : list) {
- sb.append(del);
- sb.append(item);
- del = delimeter;
- }
- return sb.toString();
- }
-
- public static String join(Collection<?> list) {
- return join(list, ",");
- }
-
- public static void split(String s, Collection<String> set) {
-
- String elements[] = s.trim().split(LIST_SPLITTER);
- for (String element : elements) {
- if (element.length() > 0)
- set.add(element);
- }
- }
-
- public static Collection<String> split(String s) {
- return split(s, LIST_SPLITTER);
- }
-
- public static Collection<String> split(String s, String splitter) {
- if (s == null || s.trim().length() == 0)
- return Collections.emptyList();
-
- return Arrays.asList(s.split(splitter));
- }
-
- public boolean isExceptions() {
- return exceptions;
- }
-
- public void setExceptions(boolean exceptions) {
- this.exceptions = exceptions;
- }
-
- /**
- * Make the file short if it is inside our base directory, otherwise long.
- *
- * @param f
- * @return
- */
- public String normalize(String f) {
- if (f.startsWith(base.getAbsolutePath() + "/"))
- return f.substring(base.getAbsolutePath().length() + 1);
- else
- return f;
- }
-
- public String normalize(File f) {
- return normalize(f.getAbsolutePath());
- }
-
- public static String removeDuplicateMarker(String key) {
- int i = key.length() - 1;
- while (i >= 0 && key.charAt(i) == DUPLICATE_MARKER)
- --i;
-
- return key.substring(0, i + 1);
- }
-
- public static boolean isDuplicate(String name) {
- return name.length() > 0
- && name.charAt(name.length() - 1) == DUPLICATE_MARKER;
- }
-
- public void setTrace(boolean x ) {
- trace = x;
- }
-
-
- static class CL extends URLClassLoader {
-
- CL() {
- super( new URL[0], Processor.class.getClassLoader() );
- }
-
- void add(URL url) {
- URL urls[] = getURLs();
- for ( URL u : urls ) {
- if ( u.equals(url))
- return;
- }
- super.addURL(url);
- }
-
- }
-
- private CL getLoader() {
- if ( pluginLoader == null )
- pluginLoader = new CL();
- return pluginLoader;
- }
-
- public boolean exists() {
- return base != null && base.exists();
- }
-
- public boolean isOk() {
- return isFailOk() || (getErrors().size()==0);
- }
- public boolean isPerfect() {
- return getErrors().size()==0 && getWarnings().size()==0;
- }
-}
-
-
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java b/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java
deleted file mode 100644
index d619f47..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Resource.java
+++ /dev/null
@@ -1,13 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-
-public interface Resource {
- InputStream openInputStream() throws IOException ;
- void write(OutputStream out) throws IOException;
- long lastModified();
- void setExtra(String extra);
- String getExtra();
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java
deleted file mode 100644
index f43ac91..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/URLResource.java
+++ /dev/null
@@ -1,39 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.net.*;
-
-public class URLResource implements Resource {
- URL url;
- String extra;
-
- public URLResource(URL url) {
- this.url = url;
- }
-
- public InputStream openInputStream() throws IOException {
- return url.openStream();
- }
-
- public String toString() {
- return ":" + url.getPath() + ":";
- }
-
- public void write(OutputStream out) throws IOException {
- FileResource.copy(this, out);
- }
-
- public long lastModified() {
- return -1;
- }
-
- public String getExtra() {
- return extra;
- }
-
- public void setExtra(String extra) {
- this.extra = extra;
- }
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java b/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java
deleted file mode 100644
index a990f51..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/Verifier.java
+++ /dev/null
@@ -1,687 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.util.*;
-import java.util.jar.*;
-import java.util.regex.*;
-
-import aQute.libg.qtokens.*;
-
-public class Verifier extends Analyzer {
-
- Jar dot;
- Manifest manifest;
- Map<String, Map<String, String>> referred = newHashMap();
- Map<String, Map<String, String>> contained = newHashMap();
- Map<String, Set<String>> uses = newHashMap();
- Map<String, Map<String, String>> mimports;
- Map<String, Map<String, String>> mdynimports;
- Map<String, Map<String, String>> mexports;
- List<Jar> bundleClasspath;
- Map<String, Map<String, String>> ignore = newHashMap(); // Packages
- // to
- // ignore
-
- Map<String, Clazz> classSpace;
- boolean r3;
- boolean usesRequire;
- boolean fragment;
- Attributes main;
-
- final static Pattern EENAME = Pattern
- .compile("CDC-1\\.0/Foundation-1\\.0"
- + "|CDC-1\\.1/Foundation-1\\.1"
- + "|OSGi/Minimum-1\\.[1-9]"
- + "|JRE-1\\.1"
- + "|J2SE-1\\.2"
- + "|J2SE-1\\.3"
- + "|J2SE-1\\.4"
- + "|J2SE-1\\.5"
- + "|JavaSE-1\\.6"
- + "|PersonalJava-1\\.1"
- + "|PersonalJava-1\\.2"
- + "|CDC-1\\.0/PersonalBasis-1\\.0"
- + "|CDC-1\\.0/PersonalJava-1\\.0");
-
- final static Pattern BUNDLEMANIFESTVERSION = Pattern
- .compile("2");
- public final static String SYMBOLICNAME_STRING = "[a-zA-Z0-9_-]+(\\.[a-zA-Z0-9_-]+)*";
- public final static Pattern SYMBOLICNAME = Pattern
- .compile(SYMBOLICNAME_STRING);
-
- public final static String VERSION_STRING = "[0-9]+(\\.[0-9]+(\\.[0-9]+(\\.[0-9A-Za-z_-]+)?)?)?";
- public final static Pattern VERSION = Pattern
- .compile(VERSION_STRING);
- final static Pattern FILTEROP = Pattern
- .compile("=|<=|>=|~=");
- final static Pattern VERSIONRANGE = Pattern
- .compile("((\\(|\\[)"
- + VERSION_STRING
- + ","
- + VERSION_STRING
- + "(\\]|\\)))|"
- + VERSION_STRING);
- final static Pattern FILE = Pattern
- .compile("/?[^/\"\n\r\u0000]+(/[^/\"\n\r\u0000]+)*");
- final static Pattern WILDCARDPACKAGE = Pattern
- .compile("((\\p{Alnum}|_)+(\\.(\\p{Alnum}|_)+)*(\\.\\*)?)|\\*");
- final static Pattern ISO639 = Pattern
- .compile("[A-Z][A-Z]");
- public static Pattern HEADER_PATTERN = Pattern
- .compile("[A-Za-z0-9][-a-zA-Z0-9_]+");
- public static Pattern TOKEN = Pattern
- .compile("[-a-zA-Z0-9_]+");
-
- Properties properties;
-
- public Verifier(Jar jar) throws Exception {
- this(jar, null);
- }
-
- public Verifier(Jar jar, Properties properties) throws Exception {
- this.dot = jar;
- this.properties = properties;
- this.manifest = jar.getManifest();
- if (manifest == null) {
- manifest = new Manifest();
- error("This file contains no manifest and is therefore not a bundle");
- }
- main = this.manifest.getMainAttributes();
- verifyHeaders(main);
- r3 = getHeader(Analyzer.BUNDLE_MANIFESTVERSION) == null;
- usesRequire = getHeader(Analyzer.REQUIRE_BUNDLE) != null;
- fragment = getHeader(Analyzer.FRAGMENT_HOST) != null;
-
- bundleClasspath = getBundleClassPath();
- mimports = parseHeader(manifest.getMainAttributes().getValue(
- Analyzer.IMPORT_PACKAGE));
- mdynimports = parseHeader(manifest.getMainAttributes().getValue(
- Analyzer.DYNAMICIMPORT_PACKAGE));
- mexports = parseHeader(manifest.getMainAttributes().getValue(
- Analyzer.EXPORT_PACKAGE));
-
- ignore = parseHeader(manifest.getMainAttributes().getValue(
- Analyzer.IGNORE_PACKAGE));
- }
-
- public Verifier() {
- // TODO Auto-generated constructor stub
- }
-
- private void verifyHeaders(Attributes main) {
- for (Object element : main.keySet()) {
- Attributes.Name header = (Attributes.Name) element;
- String h = header.toString();
- if (!HEADER_PATTERN.matcher(h).matches())
- error("Invalid Manifest header: " + h + ", pattern="
- + HEADER_PATTERN);
- }
- }
-
- private List<Jar> getBundleClassPath() {
- List<Jar> list = newList();
- String bcp = getHeader(Analyzer.BUNDLE_CLASSPATH);
- if (bcp == null) {
- list.add(dot);
- } else {
- Map<String,Map<String,String>> entries = parseHeader(bcp);
- for (String jarOrDir : entries.keySet()) {
- if (jarOrDir.equals(".")) {
- list.add(dot);
- } else {
- if (jarOrDir.equals("/"))
- jarOrDir = "";
- if (jarOrDir.endsWith("/")) {
- error("Bundle-Classpath directory must not end with a slash: "
- + jarOrDir);
- jarOrDir = jarOrDir.substring(0, jarOrDir.length() - 1);
- }
-
- Resource resource = dot.getResource(jarOrDir);
- if (resource != null) {
- try {
- Jar sub = new Jar(jarOrDir);
- addClose(sub);
- EmbeddedResource.build(sub, resource);
- if (!jarOrDir.endsWith(".jar"))
- warning("Valid JAR file on Bundle-Classpath does not have .jar extension: "
- + jarOrDir);
- list.add(sub);
- } catch (Exception e) {
- error("Invalid embedded JAR file on Bundle-Classpath: "
- + jarOrDir + ", " + e);
- }
- } else if (dot.getDirectories().containsKey(jarOrDir)) {
- if (r3)
- error("R3 bundles do not support directories on the Bundle-ClassPath: "
- + jarOrDir);
-
- try {
- Jar sub = new Jar(jarOrDir);
- addClose(sub);
- for ( Map.Entry<String, Resource> entry : dot.getResources().entrySet()) {
- if ( entry.getKey().startsWith(jarOrDir))
- sub.putResource( entry.getKey().substring(jarOrDir.length()+1), entry.getValue());
- }
- list.add(sub);
- } catch (Exception e) {
- error("Invalid embedded directory file on Bundle-Classpath: "
- + jarOrDir + ", " + e);
- }
- } else {
- error("Cannot find a file or directory for Bundle-Classpath entry: "
- + jarOrDir);
- }
- }
- }
- }
- return list;
- }
-
- /*
- * Bundle-NativeCode ::= nativecode ( ',' nativecode )* ( ’,’ optional) ?
- * nativecode ::= path ( ';' path )* // See 1.4.2 ( ';' parameter )+
- * optional ::= ’*’
- */
- public void verifyNative() {
- String nc = getHeader("Bundle-NativeCode");
- doNative(nc);
- }
-
- public void doNative(String nc) {
- if (nc != null) {
- QuotedTokenizer qt = new QuotedTokenizer(nc, ",;=", false);
- char del;
- do {
- do {
- String name = qt.nextToken();
- if (name == null) {
- error("Can not parse name from bundle native code header: "
- + nc);
- return;
- }
- del = qt.getSeparator();
- if (del == ';') {
- if (dot != null && !dot.exists(name)) {
- error("Native library not found in JAR: " + name);
- }
- } else {
- String value = null;
- if (del == '=')
- value = qt.nextToken();
-
- String key = name.toLowerCase();
- if (key.equals("osname")) {
- // ...
- } else if (key.equals("osversion")) {
- // verify version range
- verify(value, VERSIONRANGE);
- } else if (key.equals("language")) {
- verify(value, ISO639);
- } else if (key.equals("processor")) {
- // verify(value, PROCESSORS);
- } else if (key.equals("selection-filter")) {
- // verify syntax filter
- verifyFilter(value);
- } else if (name.equals("*") && value == null) {
- // Wildcard must be at end.
- if (qt.nextToken() != null)
- error("Bundle-Native code header may only END in wildcard: nc");
- } else {
- warning("Unknown attribute in native code: " + name
- + "=" + value);
- }
- del = qt.getSeparator();
- }
- } while (del == ';');
- } while (del == ',');
- }
- }
-
- public void verifyFilter(String value) {
- try {
- verifyFilter(value, 0);
- } catch (Exception e) {
- error("Not a valid filter: " + value + e.getMessage());
- }
- }
-
- private void verifyActivator() {
- String bactivator = getHeader("Bundle-Activator");
- if (bactivator != null) {
- Clazz cl = loadClass(bactivator);
- if (cl == null) {
- int n = bactivator.lastIndexOf('.');
- if (n > 0) {
- String pack = bactivator.substring(0, n);
- if (mimports.containsKey(pack))
- return;
- error("Bundle-Activator not found on the bundle class path nor in imports: "
- + bactivator);
- } else
- error("Activator uses default package and is not local (default package can not be imported): "
- + bactivator);
- }
- }
- }
-
- private Clazz loadClass(String className) {
- String path = className.replace('.', '/') + ".class";
- return (Clazz) classSpace.get(path);
- }
-
- private void verifyComponent() {
- String serviceComponent = getHeader("Service-Component");
- if (serviceComponent != null) {
- Map<String,Map<String,String>> map = parseHeader(serviceComponent);
- for (String component : map.keySet()) {
- if (!dot.exists(component)) {
- error("Service-Component entry can not be located in JAR: "
- + component);
- } else {
- // validate component ...
- }
- }
- }
- }
-
- public void info() {
- System.out.println("Refers : " + referred);
- System.out.println("Contains : " + contained);
- System.out.println("Manifest Imports : " + mimports);
- System.out.println("Manifest Exports : " + mexports);
- }
-
- /**
- * Invalid exports are exports mentioned in the manifest but not found on
- * the classpath. This can be calculated with: exports - contains.
- *
- * Unfortunately, we also must take duplicate names into account. These
- * duplicates are of course no erroneous.
- */
- private void verifyInvalidExports() {
- Set<String> invalidExport = newSet(mexports.keySet());
- invalidExport.removeAll(contained.keySet());
-
- // We might have duplicate names that are marked for it. These
- // should not be counted. Should we test them against the contained
- // set? Hmm. If someone wants to hang himself by using duplicates than
- // I guess he can go ahead ... This is not a recommended practice
- for (Iterator<String> i = invalidExport.iterator(); i.hasNext();) {
- String pack = i.next();
- if (isDuplicate(pack))
- i.remove();
- }
-
- if (!invalidExport.isEmpty())
- error("Exporting packages that are not on the Bundle-Classpath"
- + bundleClasspath + ": " + invalidExport);
- }
-
- /**
- * Invalid imports are imports that we never refer to. They can be
- * calculated by removing the refered packages from the imported packages.
- * This leaves packages that the manifest imported but that we never use.
- */
- private void verifyInvalidImports() {
- Set<String> invalidImport = newSet(mimports.keySet());
- invalidImport.removeAll(referred.keySet());
- // TODO Added this line but not sure why it worked before ...
- invalidImport.removeAll(contained.keySet());
- String bactivator = getHeader(Analyzer.BUNDLE_ACTIVATOR);
- if (bactivator != null) {
- int n = bactivator.lastIndexOf('.');
- if (n > 0) {
- invalidImport.remove(bactivator.substring(0, n));
- }
- }
- if (isPedantic() && !invalidImport.isEmpty())
- warning("Importing packages that are never refered to by any class on the Bundle-Classpath"
- + bundleClasspath + ": " + invalidImport);
- }
-
- /**
- * Check for unresolved imports. These are referals that are not imported by
- * the manifest and that are not part of our bundle classpath. The are
- * calculated by removing all the imported packages and contained from the
- * refered packages.
- */
- private void verifyUnresolvedReferences() {
- Set<String> unresolvedReferences = new TreeSet<String>(referred
- .keySet());
- unresolvedReferences.removeAll(mimports.keySet());
- unresolvedReferences.removeAll(contained.keySet());
-
- // Remove any java.** packages.
- for (Iterator<String> p = unresolvedReferences.iterator(); p.hasNext();) {
- String pack = p.next();
- if (pack.startsWith("java.") || ignore.containsKey(pack))
- p.remove();
- else {
- // Remove any dynamic imports
- if (isDynamicImport(pack))
- p.remove();
- }
- }
-
- if (!unresolvedReferences.isEmpty()) {
- // Now we want to know the
- // classes that are the culprits
- Set<String> culprits = new HashSet<String>();
- for (Clazz clazz : classSpace.values()) {
- if (hasOverlap(unresolvedReferences, clazz.imports.keySet()))
- culprits.add(clazz.getPath());
- }
-
- error("Unresolved references to " + unresolvedReferences
- + " by class(es) on the Bundle-Classpath" + bundleClasspath
- + ": " + culprits);
- }
- }
-
- /**
- * @param p
- * @param pack
- */
- private boolean isDynamicImport(String pack) {
- for (String pattern : mdynimports.keySet()) {
- // Wildcard?
- if (pattern.equals("*"))
- return true; // All packages can be dynamically imported
-
- if (pattern.endsWith(".*")) {
- pattern = pattern.substring(0, pattern.length() - 2);
- if (pack.startsWith(pattern)
- && (pack.length() == pattern.length() || pack
- .charAt(pattern.length()) == '.'))
- return true;
- } else {
- if (pack.equals(pattern))
- return true;
- }
- }
- return false;
- }
-
- private boolean hasOverlap(Set<?> a, Set<?> b) {
- for (Iterator<?> i = a.iterator(); i.hasNext();) {
- if (b.contains(i.next()))
- return true;
- }
- return false;
- }
-
- public void verify() throws IOException {
- if (classSpace == null)
- classSpace = analyzeBundleClasspath(dot,
- parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH)),
- contained, referred, uses);
- verifyManifestFirst();
- verifyActivator();
- verifyComponent();
- verifyNative();
- verifyInvalidExports();
- verifyInvalidImports();
- verifyUnresolvedReferences();
- verifySymbolicName();
- verifyListHeader("Bundle-RequiredExecutionEnvironment", EENAME, false);
- verifyHeader("Bundle-ManifestVersion", BUNDLEMANIFESTVERSION, false);
- verifyHeader("Bundle-Version", VERSION, true);
- verifyListHeader("Bundle-Classpath", FILE, false);
- verifyDynamicImportPackage();
- verifyBundleClasspath();
- if (usesRequire) {
- if (!getErrors().isEmpty()) {
- getWarnings()
- .add(
- 0,
- "Bundle uses Require Bundle, this can generate false errors because then not enough information is available without the required bundles");
- }
- }
- }
-
- public void verifyBundleClasspath() {
- Map<String,Map<String,String>> bcp = parseHeader(getHeader(Analyzer.BUNDLE_CLASSPATH));
- if ( bcp.isEmpty() || bcp.containsKey("."))
- return;
-
- for ( String path : dot.getResources().keySet()) {
- if ( path.endsWith(".class")) {
- warning("The Bundle-Classpath does not contain the actual bundle JAR (as specified with '.' in the Bundle-Classpath) but the JAR does contain classes. Is this intentional?");
- return;
- }
- }
- }
-
- /**
- * <pre>
- * DynamicImport-Package ::= dynamic-description
- * ( ',' dynamic-description )*
- *
- * dynamic-description::= wildcard-names ( ';' parameter )*
- * wildcard-names ::= wildcard-name ( ';' wildcard-name )*
- * wildcard-name ::= package-name
- * | ( package-name '.*' ) // See 1.4.2
- * | '*'
- * </pre>
- */
- private void verifyDynamicImportPackage() {
- verifyListHeader("DynamicImport-Package", WILDCARDPACKAGE, true);
- String dynamicImportPackage = getHeader("DynamicImport-Package");
- if (dynamicImportPackage == null)
- return;
-
- Map<String, Map<String,String>> map = parseHeader(dynamicImportPackage);
- for (String name : map.keySet()) {
- name = name.trim();
- if (!verify(name, WILDCARDPACKAGE))
- error("DynamicImport-Package header contains an invalid package name: "
- + name);
-
- Map<String,String> sub = map.get(name);
- if (r3 && sub.size() != 0) {
- error("DynamicPackage-Import has attributes on import: "
- + name
- + ". This is however, an <=R3 bundle and attributes on this header were introduced in R4. ");
- }
- }
- }
-
- private void verifyManifestFirst() {
- if (!dot.manifestFirst) {
- error("Invalid JAR stream: Manifest should come first to be compatible with JarInputStream, it was not");
- }
- }
-
- private void verifySymbolicName() {
- Map<String,Map<String,String>> bsn = parseHeader(getHeader(Analyzer.BUNDLE_SYMBOLICNAME));
- if (!bsn.isEmpty()) {
- if (bsn.size() > 1)
- error("More than one BSN specified " + bsn);
-
- String name = (String) bsn.keySet().iterator().next();
- if (!SYMBOLICNAME.matcher(name).matches()) {
- error("Symbolic Name has invalid format: " + name);
- }
- }
- }
-
- /**
- * <pre>
- * filter ::= ’(’ filter-comp ’)’
- * filter-comp ::= and | or | not | operation
- * and ::= ’&’ filter-list
- * or ::= ’|’ filter-list
- * not ::= ’!’ filter
- * filter-list ::= filter | filter filter-list
- * operation ::= simple | present | substring
- * simple ::= attr filter-type value
- * filter-type ::= equal | approx | greater | less
- * equal ::= ’=’
- * approx ::= ’˜=’
- * greater ::= ’>=’
- * less ::= ’<=’
- * present ::= attr ’=*’
- * substring ::= attr ’=’ initial any final
- * inital ::= () | value
- * any ::= ’*’ star-value
- * star-value ::= () | value ’*’ star-value
- * final ::= () | value
- * value ::= <see text>
- * </pre>
- *
- * @param expr
- * @param index
- * @return
- */
-
- int verifyFilter(String expr, int index) {
- try {
- while (Character.isWhitespace(expr.charAt(index)))
- index++;
-
- if (expr.charAt(index) != '(')
- throw new IllegalArgumentException(
- "Filter mismatch: expected ( at position " + index
- + " : " + expr);
-
- index++;
- while (Character.isWhitespace(expr.charAt(index)))
- index++;
-
- switch (expr.charAt(index)) {
- case '!':
- case '&':
- case '|':
- return verifyFilterSubExpression(expr, index) + 1;
-
- default:
- return verifyFilterOperation(expr, index) + 1;
- }
- } catch (IndexOutOfBoundsException e) {
- throw new IllegalArgumentException(
- "Filter mismatch: early EOF from " + index);
- }
- }
-
- private int verifyFilterOperation(String expr, int index) {
- StringBuffer sb = new StringBuffer();
- while ("=><~()".indexOf(expr.charAt(index)) < 0) {
- sb.append(expr.charAt(index++));
- }
- String attr = sb.toString().trim();
- if (attr.length() == 0)
- throw new IllegalArgumentException(
- "Filter mismatch: attr at index " + index + " is 0");
- sb = new StringBuffer();
- while ("=><~".indexOf(expr.charAt(index)) >= 0) {
- sb.append(expr.charAt(index++));
- }
- String operator = sb.toString();
- if (!verify(operator, FILTEROP))
- throw new IllegalArgumentException(
- "Filter error, illegal operator " + operator + " at index "
- + index);
-
- sb = new StringBuffer();
- while (")".indexOf(expr.charAt(index)) < 0) {
- switch (expr.charAt(index)) {
- case '\\':
- if (expr.charAt(index + 1) == '*'
- || expr.charAt(index + 1) == ')')
- index++;
- else
- throw new IllegalArgumentException(
- "Filter error, illegal use of backslash at index "
- + index
- + ". Backslash may only be used before * or (");
- }
- sb.append(expr.charAt(index++));
- }
- return index;
- }
-
- private int verifyFilterSubExpression(String expr, int index) {
- do {
- index = verifyFilter(expr, index + 1);
- while (Character.isWhitespace(expr.charAt(index)))
- index++;
- if (expr.charAt(index) != ')')
- throw new IllegalArgumentException(
- "Filter mismatch: expected ) at position " + index
- + " : " + expr);
- index++;
- } while (expr.charAt(index) == '(');
- return index;
- }
-
- private String getHeader(String string) {
- return main.getValue(string);
- }
-
- @SuppressWarnings("unchecked")
- private boolean verifyHeader(String name, Pattern regex, boolean error) {
- String value = manifest.getMainAttributes().getValue(name);
- if (value == null)
- return false;
-
- QuotedTokenizer st = new QuotedTokenizer(value.trim(), ",");
- for (Iterator<String> i = st.getTokenSet().iterator(); i.hasNext();) {
- if (!verify((String) i.next(), regex)) {
- String msg = "Invalid value for " + name + ", " + value
- + " does not match " + regex.pattern();
- if (error)
- error(msg);
- else
- warning(msg);
- }
- }
- return true;
- }
-
- private boolean verify(String value, Pattern regex) {
- return regex.matcher(value).matches();
- }
-
- private boolean verifyListHeader(String name, Pattern regex, boolean error) {
- String value = manifest.getMainAttributes().getValue(name);
- if (value == null)
- return false;
-
- Map<String,Map<String,String>> map = parseHeader(value);
- for (String header : map.keySet()) {
- if (!regex.matcher(header).matches()) {
- String msg = "Invalid value for " + name + ", " + value
- + " does not match " + regex.pattern();
- if (error)
- error(msg);
- else
- warning(msg);
- }
- }
- return true;
- }
-
- public String getProperty(String key, String deflt) {
- if (properties == null)
- return deflt;
- return properties.getProperty(key, deflt);
- }
-
- public void setClassSpace(Map<String,Clazz> classspace,
- Map<String, Map<String, String>> contained,
- Map<String, Map<String, String>> referred,
- Map<String, Set<String>> uses) {
- this.classSpace = classspace;
- this.contained = contained;
- this.referred = referred;
- this.uses = uses;
- }
-
- public static boolean isVersion(String version) {
- return VERSION.matcher(version).matches();
- }
-
-}
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java b/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java
deleted file mode 100644
index 38b744f..0000000
--- a/bundleplugin/src/main/java/aQute/lib/osgi/ZipResource.java
+++ /dev/null
@@ -1,78 +0,0 @@
-/* Copyright 2006 aQute SARL
- * Licensed under the Apache License, Version 2.0, see http://www.apache.org/licenses/LICENSE-2.0 */
-package aQute.lib.osgi;
-
-import java.io.*;
-import java.util.*;
-import java.util.regex.*;
-import java.util.zip.*;
-
-public class ZipResource implements Resource {
- ZipFile zip;
- ZipEntry entry;
- long lastModified;
- String extra;
-
- ZipResource(ZipFile zip, ZipEntry entry, long lastModified) {
- this.zip = zip;
- this.entry = entry;
- this.lastModified = lastModified;
- }
-
- public InputStream openInputStream() throws IOException {
- return zip.getInputStream(entry);
- }
-
- public String toString() {
- return ":" + entry.getName() + ":";
- }
-
- public static ZipFile build(Jar jar, File file) throws ZipException,
- IOException {
- return build(jar, file, null);
- }
-
- public static ZipFile build(Jar jar, File file, Pattern pattern)
- throws ZipException, IOException {
-
- try {
- ZipFile zip = new ZipFile(file);
- nextEntry: for (Enumeration<? extends ZipEntry> e = zip.entries(); e.hasMoreElements();) {
- ZipEntry entry = e.nextElement();
- if (pattern != null) {
- Matcher m = pattern.matcher(entry.getName());
- if (!m.matches())
- continue nextEntry;
- }
- if (!entry.isDirectory()) {
- long time = entry.getTime();
- if ( time <= 0 )
- time = file.lastModified();
- jar.putResource(entry.getName(), new ZipResource(zip,
- entry, time), true);
- }
- }
- return zip;
- } catch (FileNotFoundException e) {
- throw new IllegalArgumentException("Problem opening JAR: "
- + file.getAbsolutePath());
- }
- }
-
- public void write(OutputStream out) throws IOException {
- FileResource.copy(this, out);
- }
-
- public long lastModified() {
- return lastModified;
- }
-
- public String getExtra() {
- return extra;
- }
-
- public void setExtra(String extra) {
- this.extra = extra;
- }
-
-}