blob: c92de90f9b37b50e386e23c8a50f6a008e023f6a [file] [log] [blame]
Stuart McCullochf3173222012-06-07 21:57:32 +00001package aQute.lib.osgi;
2
3import java.io.*;
4import java.util.regex.*;
5
6public class Instruction {
Stuart McCulloch0b639c62012-06-12 12:41:16 +00007
Stuart McCullochf3173222012-06-07 21:57:32 +00008 public static class Filter implements FileFilter {
9
Stuart McCulloch0b639c62012-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 McCullochf3173222012-06-07 21:57:32 +000015 this.instruction = instruction;
16 this.recursive = recursive;
17 this.doNotCopy = doNotCopy;
18 }
Stuart McCulloch0b639c62012-06-12 12:41:16 +000019
20 public Filter(Instruction instruction, boolean recursive) {
Stuart McCullochf3173222012-06-07 21:57:32 +000021 this(instruction, recursive, Pattern.compile(Constants.DEFAULT_DO_NOT_COPY));
22 }
Stuart McCulloch0b639c62012-06-12 12:41:16 +000023
Stuart McCullochf3173222012-06-07 21:57:32 +000024 public boolean isRecursive() {
25 return recursive;
26 }
Stuart McCulloch0b639c62012-06-12 12:41:16 +000027
Stuart McCullochf3173222012-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 McCulloch0b639c62012-06-12 12:41:16 +000036
Stuart McCullochf3173222012-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 McCulloch0b639c62012-06-12 12:41:16 +000053
Stuart McCullochf3173222012-06-07 21:57:32 +000054 public Instruction(String input) {
55 this.input = input;
Stuart McCulloch0b639c62012-06-12 12:41:16 +000056
Stuart McCullochf3173222012-06-07 21:57:32 +000057 String s = Processor.removeDuplicateMarker(input);
58 duplicate = !s.equals(input);
Stuart McCulloch0b639c62012-06-12 12:41:16 +000059
Stuart McCullochf3173222012-06-07 21:57:32 +000060 if (s.startsWith("!")) {
61 negated = true;
62 s = s.substring(1);
Stuart McCulloch4482c702012-06-15 13:27:53 +000063 } else
Stuart McCullochf3173222012-06-07 21:57:32 +000064 negated = false;
65
Stuart McCulloch0b639c62012-06-12 12:41:16 +000066 if (input.equals("*")) {
Stuart McCullochf3173222012-06-07 21:57:32 +000067 any = true;
Stuart McCulloch0b639c62012-06-12 12:41:16 +000068 literal = false;
69 match = null;
Stuart McCullochf3173222012-06-07 21:57:32 +000070 return;
71 }
Stuart McCulloch0b639c62012-06-12 12:41:16 +000072
Stuart McCullochf3173222012-06-07 21:57:32 +000073 any = false;
74 if (s.startsWith("=")) {
75 match = s.substring(1);
76 literal = true;
Stuart McCulloch4482c702012-06-15 13:27:53 +000077 } else {
Stuart McCullochf3173222012-06-07 21:57:32 +000078 boolean wildcards = false;
Stuart McCulloch0b639c62012-06-12 12:41:16 +000079
Stuart McCullochf3173222012-06-07 21:57:32 +000080 StringBuilder sb = new StringBuilder();
81 loop: for (int c = 0; c < s.length(); c++) {
82 switch (s.charAt(c)) {
Stuart McCulloch0b639c62012-06-12 12:41:16 +000083 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 McCulloch4482c702012-06-15 13:27:53 +000091 } else
Stuart McCulloch0b639c62012-06-12 12:41:16 +000092 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 McCullochf3173222012-06-07 21:57:32 +0000113 }
114 }
Stuart McCulloch0b639c62012-06-12 12:41:16 +0000115
116 if (!wildcards) {
Stuart McCullochf3173222012-06-07 21:57:32 +0000117 literal = true;
118 match = s;
Stuart McCulloch4482c702012-06-15 13:27:53 +0000119 } else {
Stuart McCullochf3173222012-06-07 21:57:32 +0000120 literal = false;
121 match = sb.toString();
122 }
123 }
124
Stuart McCullochf3173222012-06-07 21:57:32 +0000125 }
126
127 public boolean matches(String value) {
128 if (any)
129 return true;
Stuart McCulloch0b639c62012-06-12 12:41:16 +0000130
131 if (literal)
Stuart McCullochf3173222012-06-07 21:57:32 +0000132 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 McCullochf3173222012-06-07 21:57:32 +0000168 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}