Temporarily include bndlib 1.47 for testing purposes (not yet on central)
git-svn-id: https://svn.apache.org/repos/asf/felix/trunk@1185095 13f79535-47bb-0310-9956-ffa450edef68
diff --git a/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
new file mode 100644
index 0000000..f466f57
--- /dev/null
+++ b/bundleplugin/src/main/java/aQute/lib/osgi/Instruction.java
@@ -0,0 +1,130 @@
+package aQute.lib.osgi;
+
+import java.util.*;
+import java.util.regex.*;
+
+import aQute.libg.generics.*;
+
+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;
+ }
+
+ public static Map<Instruction, Map<String, String>> replaceWithInstruction(
+ Map<String, Map<String, String>> header) {
+ Map<Instruction, Map<String, String>> map = Processor.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 = getPattern(pattern);
+ String presence = entry.getValue()
+ .get(Constants.PRESENCE_DIRECTIVE);
+ if ("optional".equals(presence))
+ instr.setOptional();
+ map.put(instr, entry.getValue());
+ }
+ return map;
+ }
+
+ public static <T> Collection<T> select(Collection<Instruction> matchers,
+ Collection<T> targets) {
+ Collection<T> result = Create.list();
+ outer: for (T t : targets) {
+ String s = t.toString();
+ for (Instruction i : matchers) {
+ if (i.matches(s)) {
+ if (!i.isNegated())
+ result.add(t);
+ continue outer;
+ }
+ }
+ }
+ return result;
+ }
+}