1. /*
  2. * @(#)MatchQueryExp.java 1.25 03/12/19
  3. *
  4. * Copyright 2004 Sun Microsystems, Inc. All rights reserved.
  5. * SUN PROPRIETARY/CONFIDENTIAL. Use is subject to license terms.
  6. */
  7. package javax.management;
  8. /**
  9. * This class is used by the query-building mechanism to represent binary
  10. * relations.
  11. * @serial include
  12. *
  13. * @since 1.5
  14. */
  15. class MatchQueryExp extends QueryEval implements QueryExp {
  16. /* Serial version */
  17. private static final long serialVersionUID = -7156603696948215014L;
  18. /**
  19. * @serial The attribute value to be matched
  20. */
  21. private AttributeValueExp exp;
  22. /**
  23. * @serial The pattern to be matched
  24. */
  25. private String pattern;
  26. /**
  27. * Basic Constructor.
  28. */
  29. public MatchQueryExp() {
  30. }
  31. /**
  32. * Creates a new MatchQueryExp where the specified AttributeValueExp matches
  33. * the specified pattern StringValueExp.
  34. */
  35. public MatchQueryExp(AttributeValueExp a, StringValueExp s) {
  36. exp = a;
  37. pattern = s.getValue();
  38. }
  39. /**
  40. * Returns the attribute of the query.
  41. */
  42. public AttributeValueExp getAttribute() {
  43. return exp;
  44. }
  45. /**
  46. * Returns the pattern of the query.
  47. */
  48. public String getPattern() {
  49. return pattern;
  50. }
  51. /**
  52. * Applies the MatchQueryExp on a MBean.
  53. *
  54. * @param name The name of the MBean on which the MatchQueryExp will be applied.
  55. *
  56. * @return True if the query was successfully applied to the MBean, false otherwise.
  57. *
  58. * @exception BadStringOperationException
  59. * @exception BadBinaryOpValueExpException
  60. * @exception BadAttributeValueExpException
  61. * @exception InvalidApplicationException
  62. */
  63. public boolean apply(ObjectName name) throws BadStringOperationException, BadBinaryOpValueExpException,
  64. BadAttributeValueExpException, InvalidApplicationException {
  65. ValueExp val = exp.apply(name);
  66. if (!(val instanceof StringValueExp)) {
  67. return false;
  68. }
  69. return wildmatch(((StringValueExp)val).getValue(), pattern);
  70. }
  71. /**
  72. * Returns the string representing the object
  73. */
  74. public String toString() {
  75. return exp + " like " + new StringValueExp(likeTranslate(pattern));
  76. }
  77. private static String likeTranslate(String s) {
  78. return s.replace('?', '_').replace('*', '%');
  79. }
  80. /*
  81. * Tests whether string s is matched by pattern p.
  82. * Supports "?", "*", "[", each of which may be escaped with "\";
  83. * Character classes may use "!" for negation and "-" for range.
  84. * Not yet supported: internationalization; "\" inside brackets.<P>
  85. * Wildcard matching routine by Karl Heuer. Public Domain.<P>
  86. */
  87. private static boolean wildmatch(String s, String p) {
  88. char c;
  89. int si = 0, pi = 0;
  90. int slen = s.length();
  91. int plen = p.length();
  92. while (pi < plen) { // While still string
  93. c = p.charAt(pi++);
  94. if (c == '?') {
  95. if (++si > slen)
  96. return false;
  97. } else if (c == '[') { // Start of choice
  98. boolean wantit = true;
  99. boolean seenit = false;
  100. if (p.charAt(pi) == '!') {
  101. wantit = false;
  102. ++pi;
  103. }
  104. while (++pi < plen && (c = p.charAt(pi)) != ']') {
  105. if (p.charAt(pi) == '-' && pi+1 < plen) {
  106. if (s.charAt(si) >= c && s.charAt(si) <= p.charAt(pi+1)) {
  107. seenit = true;
  108. }
  109. pi += 1;
  110. } else {
  111. if (c == s.charAt(si)) {
  112. seenit = true;
  113. }
  114. }
  115. }
  116. if ((pi >= plen) || (wantit != seenit)) {
  117. return false;
  118. }
  119. ++pi;
  120. ++si;
  121. } else if (c == '*') { // Wildcard
  122. if (pi >= plen)
  123. return true;
  124. do {
  125. if (wildmatch(s.substring(si), p.substring(pi)))
  126. return true;
  127. } while (++si < slen);
  128. return false;
  129. } else if (c == '\\') {
  130. if (pi >= plen || p.charAt(pi++) != s.charAt(si++))
  131. return false;
  132. } else {
  133. if (si >= slen || c != s.charAt(si++)) {
  134. return false;
  135. }
  136. }
  137. }
  138. return (si == slen);
  139. }
  140. }