195 // If this property is ok (same key, same value), go to next |
194 // If this property is ok (same key, same value), go to next |
196 // |
195 // |
197 if (isPropertyValuePattern && |
196 if (isPropertyValuePattern && |
198 pattern.isPropertyValuePattern(keys[i])) { |
197 pattern.isPropertyValuePattern(keys[i])) { |
199 // wildmatch key property values |
198 // wildmatch key property values |
200 final char[] val_pattern = values[i].toCharArray(); |
199 // values[i] is the pattern; |
201 final char[] val_string = v.toCharArray(); |
200 // v is the string |
202 if (wildmatch(val_string,val_pattern)) |
201 if (Util.wildmatch(v,values[i])) |
203 continue; |
202 continue; |
204 else |
203 else |
205 return false; |
204 return false; |
206 } |
205 } |
207 if (v.equals(values[i])) continue; |
206 if (v.equals(values[i])) continue; |
234 if (pattern.matchKeys(on)) result.add(no); |
233 if (pattern.matchKeys(on)) result.add(no); |
235 } |
234 } |
236 } |
235 } |
237 } |
236 } |
238 |
237 |
239 /** Match a string against a shell-style pattern. The only pattern |
|
240 characters recognised are <code>?</code>, standing for any one |
|
241 character, and <code>*</code>, standing for any string of |
|
242 characters, including the empty string. |
|
243 |
|
244 @param str the string to match, as a character array. |
|
245 @param pat the pattern to match the string against, as a |
|
246 character array. |
|
247 |
|
248 @return true if and only if the string matches the pattern. |
|
249 */ |
|
250 /* The algorithm is a classical one. We advance pointers in |
|
251 parallel through str and pat. If we encounter a star in pat, |
|
252 we remember its position and continue advancing. If at any |
|
253 stage we get a mismatch between str and pat, we look to see if |
|
254 there is a remembered star. If not, we fail. If so, we |
|
255 retreat pat to just past that star and str to the position |
|
256 after the last one we tried, and we let the match advance |
|
257 again. |
|
258 |
|
259 Even though there is only one remembered star position, the |
|
260 algorithm works when there are several stars in the pattern. |
|
261 When we encounter the second star, we forget the first one. |
|
262 This is OK, because if we get to the second star in A*B*C |
|
263 (where A etc are arbitrary strings), we have already seen AXB. |
|
264 We're therefore setting up a match of *C against the remainder |
|
265 of the string, which will match if that remainder looks like |
|
266 YC, so the whole string looks like AXBYC. |
|
267 */ |
|
268 public static boolean wildmatch(char[] str, char[] pat) { |
|
269 int stri; // index in str |
|
270 int pati; // index in pat |
|
271 int starstri; // index for backtrack if "*" attempt fails |
|
272 int starpati; // index for backtrack if "*" attempt fails, +1 |
|
273 final int strlen = str.length; |
|
274 final int patlen = pat.length; |
|
275 |
|
276 stri = pati = 0; |
|
277 starstri = starpati = -1; |
|
278 |
|
279 /* On each pass through this loop, we either advance pati, |
|
280 or we backtrack pati and advance starstri. Since starstri |
|
281 is only ever assigned from pati, the loop must terminate. */ |
|
282 while (true) { |
|
283 if (pati < patlen) { |
|
284 final char patc = pat[pati]; |
|
285 switch (patc) { |
|
286 case '?': |
|
287 if (stri == strlen) |
|
288 break; |
|
289 stri++; |
|
290 pati++; |
|
291 continue; |
|
292 case '*': |
|
293 pati++; |
|
294 starpati = pati; |
|
295 starstri = stri; |
|
296 continue; |
|
297 default: |
|
298 if (stri < strlen && str[stri] == patc) { |
|
299 stri++; |
|
300 pati++; |
|
301 continue; |
|
302 } |
|
303 break; |
|
304 } |
|
305 } else if (stri == strlen) |
|
306 return true; |
|
307 |
|
308 // Mismatched, can we backtrack to a "*"? |
|
309 if (starpati < 0 || starstri == strlen) |
|
310 return false; |
|
311 |
|
312 // Retry the match one position later in str |
|
313 pati = starpati; |
|
314 starstri++; |
|
315 stri = starstri; |
|
316 } |
|
317 } |
|
318 |
|
319 private void addNewDomMoi(final DynamicMBean object, |
238 private void addNewDomMoi(final DynamicMBean object, |
320 final String dom, |
239 final String dom, |
321 final ObjectName name, |
240 final ObjectName name, |
322 final RegistrationContext context) { |
241 final RegistrationContext context) { |
323 final Map<String,NamedObject> moiTb = |
242 final Map<String,NamedObject> moiTb = |
478 // Set domain to default if domain is empty and not already set |
397 // Set domain to default if domain is empty and not already set |
479 if (dom.length() == 0) |
398 if (dom.length() == 0) |
480 name = Util.newObjectName(domain + name.toString()); |
399 name = Util.newObjectName(domain + name.toString()); |
481 |
400 |
482 // Do we have default domain ? |
401 // Do we have default domain ? |
483 if (dom == domain) { |
402 if (dom == domain) { // ES: OK (dom & domain are interned) |
484 to_default_domain = true; |
403 to_default_domain = true; |
485 dom = domain; |
404 dom = domain; |
486 } else { |
405 } else { |
487 to_default_domain = false; |
406 to_default_domain = false; |
488 } |
407 } |
650 addAllMatching(moiTb, result, namePattern); |
569 addAllMatching(moiTb, result, namePattern); |
651 return result; |
570 return result; |
652 } |
571 } |
653 |
572 |
654 // Pattern matching in the domain name (*, ?) |
573 // Pattern matching in the domain name (*, ?) |
655 char[] dom2Match = name.getDomain().toCharArray(); |
574 final String dom2Match = name.getDomain(); |
656 for (String dom : domainTb.keySet()) { |
575 for (String dom : domainTb.keySet()) { |
657 char[] theDom = dom.toCharArray(); |
576 if (Util.wildpathmatch(dom, dom2Match)) { |
658 if (wildmatch(theDom, dom2Match)) { |
|
659 final Map<String,NamedObject> moiTb = domainTb.get(dom); |
577 final Map<String,NamedObject> moiTb = domainTb.get(dom); |
660 if (allNames) |
578 if (allNames) |
661 result.addAll(moiTb.values()); |
579 result.addAll(moiTb.values()); |
662 else |
580 else |
663 addAllMatching(moiTb, result, namePattern); |
581 addAllMatching(moiTb, result, namePattern); |
724 |
642 |
725 // set a new default domain table (always present) |
643 // set a new default domain table (always present) |
726 // need to reinstantiate a hashtable because of possible |
644 // need to reinstantiate a hashtable because of possible |
727 // big buckets array size inside table, never cleared, |
645 // big buckets array size inside table, never cleared, |
728 // thus the new ! |
646 // thus the new ! |
729 if (dom == domain) |
647 if (dom == domain) // ES: OK dom and domain are interned. |
730 domainTb.put(domain, new HashMap<String,NamedObject>()); |
648 domainTb.put(domain, new HashMap<String,NamedObject>()); |
731 } |
649 } |
732 |
650 |
733 unregistering(context,name); |
651 unregistering(context,name); |
734 |
652 |