Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 1 | package aQute.lib.osgi; |
| 2 | |
| 3 | import java.io.*; |
| 4 | import java.util.regex.*; |
| 5 | |
| 6 | public class Instruction { |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 7 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 8 | public static class Filter implements FileFilter { |
| 9 | |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 10 | private Instruction instruction; |
| 11 | private boolean recursive; |
| 12 | private Pattern doNotCopy; |
| 13 | |
| 14 | public Filter(Instruction instruction, boolean recursive, Pattern doNotCopy) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 15 | this.instruction = instruction; |
| 16 | this.recursive = recursive; |
| 17 | this.doNotCopy = doNotCopy; |
| 18 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 19 | |
| 20 | public Filter(Instruction instruction, boolean recursive) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 21 | this(instruction, recursive, Pattern.compile(Constants.DEFAULT_DO_NOT_COPY)); |
| 22 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 23 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 24 | public boolean isRecursive() { |
| 25 | return recursive; |
| 26 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 27 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 28 | public boolean accept(File pathname) { |
| 29 | if (doNotCopy != null && doNotCopy.matcher(pathname.getName()).matches()) { |
| 30 | return false; |
| 31 | } |
| 32 | |
| 33 | if (pathname.isDirectory() && isRecursive()) { |
| 34 | return true; |
| 35 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 36 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 37 | if (instruction == null) { |
| 38 | return true; |
| 39 | } |
| 40 | return !instruction.isNegated() == instruction.matches(pathname.getName()); |
| 41 | } |
| 42 | } |
| 43 | |
| 44 | transient Pattern pattern; |
| 45 | transient boolean optional; |
| 46 | |
| 47 | final String input; |
| 48 | final String match; |
| 49 | final boolean negated; |
| 50 | final boolean duplicate; |
| 51 | final boolean literal; |
| 52 | final boolean any; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 53 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 54 | public Instruction(String input) { |
| 55 | this.input = input; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 56 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 57 | String s = Processor.removeDuplicateMarker(input); |
| 58 | duplicate = !s.equals(input); |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 59 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 60 | if (s.startsWith("!")) { |
| 61 | negated = true; |
| 62 | s = s.substring(1); |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame^] | 63 | } else |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 64 | negated = false; |
| 65 | |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 66 | if (input.equals("*")) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 67 | any = true; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 68 | literal = false; |
| 69 | match = null; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 70 | return; |
| 71 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 72 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 73 | any = false; |
| 74 | if (s.startsWith("=")) { |
| 75 | match = s.substring(1); |
| 76 | literal = true; |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame^] | 77 | } else { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 78 | boolean wildcards = false; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 79 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 80 | StringBuilder sb = new StringBuilder(); |
| 81 | loop: for (int c = 0; c < s.length(); c++) { |
| 82 | switch (s.charAt(c)) { |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 83 | case '.' : |
| 84 | // If we end in a wildcard .* then we need to |
| 85 | // also include the last full package. I.e. |
| 86 | // com.foo.* includes com.foo (unlike OSGi) |
| 87 | if (c == s.length() - 2 && '*' == s.charAt(c + 1)) { |
| 88 | sb.append("(\\..*)?"); |
| 89 | wildcards = true; |
| 90 | break loop; |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame^] | 91 | } else |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 92 | sb.append("\\."); |
| 93 | |
| 94 | break; |
| 95 | case '*' : |
| 96 | sb.append(".*"); |
| 97 | wildcards = true; |
| 98 | break; |
| 99 | case '$' : |
| 100 | sb.append("\\$"); |
| 101 | break; |
| 102 | case '?' : |
| 103 | sb.append(".?"); |
| 104 | wildcards = true; |
| 105 | break; |
| 106 | case '|' : |
| 107 | sb.append('|'); |
| 108 | wildcards = true; |
| 109 | break; |
| 110 | default : |
| 111 | sb.append(s.charAt(c)); |
| 112 | break; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 113 | } |
| 114 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 115 | |
| 116 | if (!wildcards) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 117 | literal = true; |
| 118 | match = s; |
Stuart McCulloch | 2286f23 | 2012-06-15 13:27:53 +0000 | [diff] [blame^] | 119 | } else { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 120 | literal = false; |
| 121 | match = sb.toString(); |
| 122 | } |
| 123 | } |
| 124 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 125 | } |
| 126 | |
| 127 | public boolean matches(String value) { |
| 128 | if (any) |
| 129 | return true; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 130 | |
| 131 | if (literal) |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 132 | return match.equals(value); |
| 133 | else |
| 134 | return getMatcher(value).matches(); |
| 135 | } |
| 136 | |
| 137 | public boolean isNegated() { |
| 138 | return negated; |
| 139 | } |
| 140 | |
| 141 | public String getPattern() { |
| 142 | return match; |
| 143 | } |
| 144 | |
| 145 | public String getInput() { |
| 146 | return input; |
| 147 | } |
| 148 | |
| 149 | public String toString() { |
| 150 | return input; |
| 151 | } |
| 152 | |
| 153 | public Matcher getMatcher(String value) { |
| 154 | if (pattern == null) { |
| 155 | pattern = Pattern.compile(match); |
| 156 | } |
| 157 | return pattern.matcher(value); |
| 158 | } |
| 159 | |
| 160 | public void setOptional() { |
| 161 | optional = true; |
| 162 | } |
| 163 | |
| 164 | public boolean isOptional() { |
| 165 | return optional; |
| 166 | } |
| 167 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 168 | public boolean isLiteral() { |
| 169 | return literal; |
| 170 | } |
| 171 | |
| 172 | public String getLiteral() { |
| 173 | assert literal; |
| 174 | return match; |
| 175 | } |
| 176 | |
| 177 | public boolean isDuplicate() { |
| 178 | return duplicate; |
| 179 | } |
| 180 | |
| 181 | public boolean isAny() { |
| 182 | return any; |
| 183 | } |
| 184 | |
| 185 | } |