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 | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 63 | } |
| 64 | else |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 65 | negated = false; |
| 66 | |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 67 | if (input.equals("*")) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 68 | any = true; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 69 | literal = false; |
| 70 | match = null; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 71 | return; |
| 72 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 73 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 74 | any = false; |
| 75 | if (s.startsWith("=")) { |
| 76 | match = s.substring(1); |
| 77 | literal = true; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 78 | } |
| 79 | else { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 80 | boolean wildcards = false; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 81 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 82 | StringBuilder sb = new StringBuilder(); |
| 83 | loop: for (int c = 0; c < s.length(); c++) { |
| 84 | switch (s.charAt(c)) { |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 85 | case '.' : |
| 86 | // If we end in a wildcard .* then we need to |
| 87 | // also include the last full package. I.e. |
| 88 | // com.foo.* includes com.foo (unlike OSGi) |
| 89 | if (c == s.length() - 2 && '*' == s.charAt(c + 1)) { |
| 90 | sb.append("(\\..*)?"); |
| 91 | wildcards = true; |
| 92 | break loop; |
| 93 | } |
| 94 | else |
| 95 | sb.append("\\."); |
| 96 | |
| 97 | break; |
| 98 | case '*' : |
| 99 | sb.append(".*"); |
| 100 | wildcards = true; |
| 101 | break; |
| 102 | case '$' : |
| 103 | sb.append("\\$"); |
| 104 | break; |
| 105 | case '?' : |
| 106 | sb.append(".?"); |
| 107 | wildcards = true; |
| 108 | break; |
| 109 | case '|' : |
| 110 | sb.append('|'); |
| 111 | wildcards = true; |
| 112 | break; |
| 113 | default : |
| 114 | sb.append(s.charAt(c)); |
| 115 | break; |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 116 | } |
| 117 | } |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 118 | |
| 119 | if (!wildcards) { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 120 | literal = true; |
| 121 | match = s; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 122 | } |
| 123 | else { |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 124 | literal = false; |
| 125 | match = sb.toString(); |
| 126 | } |
| 127 | } |
| 128 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 129 | } |
| 130 | |
| 131 | public boolean matches(String value) { |
| 132 | if (any) |
| 133 | return true; |
Stuart McCulloch | 285034f | 2012-06-12 12:41:16 +0000 | [diff] [blame] | 134 | |
| 135 | if (literal) |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 136 | return match.equals(value); |
| 137 | else |
| 138 | return getMatcher(value).matches(); |
| 139 | } |
| 140 | |
| 141 | public boolean isNegated() { |
| 142 | return negated; |
| 143 | } |
| 144 | |
| 145 | public String getPattern() { |
| 146 | return match; |
| 147 | } |
| 148 | |
| 149 | public String getInput() { |
| 150 | return input; |
| 151 | } |
| 152 | |
| 153 | public String toString() { |
| 154 | return input; |
| 155 | } |
| 156 | |
| 157 | public Matcher getMatcher(String value) { |
| 158 | if (pattern == null) { |
| 159 | pattern = Pattern.compile(match); |
| 160 | } |
| 161 | return pattern.matcher(value); |
| 162 | } |
| 163 | |
| 164 | public void setOptional() { |
| 165 | optional = true; |
| 166 | } |
| 167 | |
| 168 | public boolean isOptional() { |
| 169 | return optional; |
| 170 | } |
| 171 | |
Stuart McCulloch | bb01437 | 2012-06-07 21:57:32 +0000 | [diff] [blame] | 172 | public boolean isLiteral() { |
| 173 | return literal; |
| 174 | } |
| 175 | |
| 176 | public String getLiteral() { |
| 177 | assert literal; |
| 178 | return match; |
| 179 | } |
| 180 | |
| 181 | public boolean isDuplicate() { |
| 182 | return duplicate; |
| 183 | } |
| 184 | |
| 185 | public boolean isAny() { |
| 186 | return any; |
| 187 | } |
| 188 | |
| 189 | } |