blob: 9263e3c12101329c5430a46c3956ac0b005f2e82 [file] [log] [blame]
Stuart McCullochbb014372012-06-07 21:57:32 +00001package aQute.lib.osgi;
2
3import java.io.*;
4import java.util.regex.*;
5
6public class Instruction {
Stuart McCulloch285034f2012-06-12 12:41:16 +00007
Stuart McCullochbb014372012-06-07 21:57:32 +00008 public static class Filter implements FileFilter {
9
Stuart McCulloch285034f2012-06-12 12:41:16 +000010 private Instruction instruction;
11 private boolean recursive;
12 private Pattern doNotCopy;
13
14 public Filter(Instruction instruction, boolean recursive, Pattern doNotCopy) {
Stuart McCullochbb014372012-06-07 21:57:32 +000015 this.instruction = instruction;
16 this.recursive = recursive;
17 this.doNotCopy = doNotCopy;
18 }
Stuart McCulloch285034f2012-06-12 12:41:16 +000019
20 public Filter(Instruction instruction, boolean recursive) {
Stuart McCullochbb014372012-06-07 21:57:32 +000021 this(instruction, recursive, Pattern.compile(Constants.DEFAULT_DO_NOT_COPY));
22 }
Stuart McCulloch285034f2012-06-12 12:41:16 +000023
Stuart McCullochbb014372012-06-07 21:57:32 +000024 public boolean isRecursive() {
25 return recursive;
26 }
Stuart McCulloch285034f2012-06-12 12:41:16 +000027
Stuart McCullochbb014372012-06-07 21:57:32 +000028 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 McCulloch285034f2012-06-12 12:41:16 +000036
Stuart McCullochbb014372012-06-07 21:57:32 +000037 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 McCulloch285034f2012-06-12 12:41:16 +000053
Stuart McCullochbb014372012-06-07 21:57:32 +000054 public Instruction(String input) {
55 this.input = input;
Stuart McCulloch285034f2012-06-12 12:41:16 +000056
Stuart McCullochbb014372012-06-07 21:57:32 +000057 String s = Processor.removeDuplicateMarker(input);
58 duplicate = !s.equals(input);
Stuart McCulloch285034f2012-06-12 12:41:16 +000059
Stuart McCullochbb014372012-06-07 21:57:32 +000060 if (s.startsWith("!")) {
61 negated = true;
62 s = s.substring(1);
Stuart McCulloch285034f2012-06-12 12:41:16 +000063 }
64 else
Stuart McCullochbb014372012-06-07 21:57:32 +000065 negated = false;
66
Stuart McCulloch285034f2012-06-12 12:41:16 +000067 if (input.equals("*")) {
Stuart McCullochbb014372012-06-07 21:57:32 +000068 any = true;
Stuart McCulloch285034f2012-06-12 12:41:16 +000069 literal = false;
70 match = null;
Stuart McCullochbb014372012-06-07 21:57:32 +000071 return;
72 }
Stuart McCulloch285034f2012-06-12 12:41:16 +000073
Stuart McCullochbb014372012-06-07 21:57:32 +000074 any = false;
75 if (s.startsWith("=")) {
76 match = s.substring(1);
77 literal = true;
Stuart McCulloch285034f2012-06-12 12:41:16 +000078 }
79 else {
Stuart McCullochbb014372012-06-07 21:57:32 +000080 boolean wildcards = false;
Stuart McCulloch285034f2012-06-12 12:41:16 +000081
Stuart McCullochbb014372012-06-07 21:57:32 +000082 StringBuilder sb = new StringBuilder();
83 loop: for (int c = 0; c < s.length(); c++) {
84 switch (s.charAt(c)) {
Stuart McCulloch285034f2012-06-12 12:41:16 +000085 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 McCullochbb014372012-06-07 21:57:32 +0000116 }
117 }
Stuart McCulloch285034f2012-06-12 12:41:16 +0000118
119 if (!wildcards) {
Stuart McCullochbb014372012-06-07 21:57:32 +0000120 literal = true;
121 match = s;
Stuart McCulloch285034f2012-06-12 12:41:16 +0000122 }
123 else {
Stuart McCullochbb014372012-06-07 21:57:32 +0000124 literal = false;
125 match = sb.toString();
126 }
127 }
128
Stuart McCullochbb014372012-06-07 21:57:32 +0000129 }
130
131 public boolean matches(String value) {
132 if (any)
133 return true;
Stuart McCulloch285034f2012-06-12 12:41:16 +0000134
135 if (literal)
Stuart McCullochbb014372012-06-07 21:57:32 +0000136 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 McCullochbb014372012-06-07 21:57:32 +0000172 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}