1/* 2 * Copyright (c) 2006, 2015, Oracle and/or its affiliates. All rights reserved. 3 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER. 4 * 5 * This code is free software; you can redistribute it and/or modify it 6 * under the terms of the GNU General Public License version 2 only, as 7 * published by the Free Software Foundation. 8 * 9 * This code is distributed in the hope that it will be useful, but WITHOUT 10 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or 11 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License 12 * version 2 for more details (a copy is included in the LICENSE file that 13 * accompanied this code). 14 * 15 * You should have received a copy of the GNU General Public License version 16 * 2 along with this work; if not, write to the Free Software Foundation, 17 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA. 18 * 19 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA 20 * or visit www.oracle.com if you need additional information or have any 21 * questions. 22 */ 23 24import java.util.ArrayList; 25 26import javax.management.Query; 27import javax.management.QueryExp; 28import javax.management.ValueExp; 29 30/** 31 * Class used for building QueryExp instances of all every possible type 32 * in terms of JMX API members; note that several JMX classes are private 33 * and appears in the JDK API only by their serial form. 34 * Comments in each case of the big switch in method getQuery() details which 35 * API member we cover with a given query. 36 */ 37public class QueryFactory extends QueryData { 38 39 private String mbeanClassName = ""; 40 private String primitiveIntAttName = "IntAtt"; 41 private String primitiveLongAttName = "LongAtt"; 42 private String integerAttName = "IntegerAtt"; 43 private String primitiveBooleanAttName = "BooleanAtt"; 44 private String primitiveDoubleAttName = "DoubleAtt"; 45 private String primitiveFloatAttName = "FloatAtt"; 46 private String stringAttName = "StringAtt"; 47 private ArrayList<QueryExp> queries = new ArrayList<QueryExp>(); 48 49 /** 50 * Creates a new instance of QueryFactory. 51 * The name is the fully qualified class name of an MBean. 52 * There is severe constraints on that MBean that must: 53 * <ul> 54 * <li>extend QueryData in order to inherit attribute values. 55 * <li>define a RW attribute IntAtt of type int 56 * initialized to QueryData.longValue 57 * <li>define a RW attribute LongAtt of type long 58 * initialized to QueryData.intValue 59 * <li>define a RW attribute IntegerAtt of type Integer 60 * initialized to QueryData.integerValue 61 * <li>define a RW attribute BooleanAtt of type boolean 62 * initialized to QueryData.booleanValue 63 * <li>define a RW attribute DoubleAtt of type double 64 * initialized to QueryData.doubleValue 65 * <li>define a RW attribute FloatAtt of type float 66 * initialized to QueryData.floatValue 67 * <li>define a RW attribute StringAtt of type String 68 * initialized to QueryData.stringValue 69 * </ul> 70 */ 71 public QueryFactory(String name) { 72 this.mbeanClassName = name; 73 } 74 75 /** 76 * Returns the highest index value the method getQuery supports. 77 * WARNING : returns 0 if buildQueries haven't been called first ! 78 */ 79 public int getSize() { 80 return queries.size(); 81 } 82 83 /** 84 * Populates an ArrayList of QueryExp. 85 * Lowest index is 1. 86 * Highest index is returned by getSize(). 87 * <br>The queries numbered 1 to 23 allow to cover all the underlying 88 * Java classes of the JMX API used to build queries. 89 */ 90 public void buildQueries() { 91 if ( queries.size() == 0 ) { 92 int smallerIntValue = intValue - 1; 93 int biggerIntValue = intValue + 1; 94 95 // case 1: 96 // True if the MBean is of class mbeanClassName 97 // We cover javax.management.InstanceOfQueryExp 98 queries.add(Query.isInstanceOf(Query.value(mbeanClassName))); 99 100 // case 2: 101 // True if the MBean is of class mbeanClassName 102 // We cover javax.management.MatchQueryExp and 103 // javax.management.ClassAttributeValueExp 104 queries.add(Query.match(Query.classattr(), 105 Query.value(mbeanClassName))); 106 107 // case 3: 108 // True if an attribute named primitiveIntAttName of type int has 109 // the value intValue 110 // We cover javax.management.BinaryRelQueryExp with 111 // a relOp equal to EQ and javax.management.NumericValueExp 112 queries.add(Query.eq(Query.attr(primitiveIntAttName), 113 Query.value(intValue))); 114 115 // case 4: 116 // True if an attribute named primitiveLongAttName of type long has 117 // the value longValue 118 // We cover javax.management.BinaryRelQueryExp with 119 // a relOp equal to EQ and javax.management.NumericValueExp 120 queries.add(Query.eq(Query.attr(primitiveLongAttName), 121 Query.value(longValue))); 122 123 // case 5: 124 // True if an attribute named primitiveDoubleAttName of type double 125 // has the value doubleValue 126 // We cover javax.management.BinaryRelQueryExp with 127 // a relOp equal to EQ and javax.management.NumericValueExp 128 queries.add(Query.eq(Query.attr(primitiveDoubleAttName), 129 Query.value(doubleValue))); 130 131 // case 6: 132 // True if an attribute named primitiveFloatAttName of type float 133 // has the value floatValue 134 // We cover javax.management.BinaryRelQueryExp with 135 // a relOp equal to EQ and javax.management.NumericValueExp 136 queries.add(Query.eq(Query.attr(primitiveFloatAttName), 137 Query.value(floatValue))); 138 139 // case 7: 140 // True if an attribute named primitiveIntAttName of type int is 141 // hold by an MBean of class mbeanClassName and has 142 // the value intValue 143 // We cover javax.management.QualifiedAttributeValueExp 144 queries.add(Query.eq(Query.attr(mbeanClassName, primitiveIntAttName), 145 Query.value(intValue))); 146 147 // case 8: 148 // True if an attribute named stringAttName of type String has 149 // the value stringValue 150 // We cover javax.management.BinaryRelQueryExp with 151 // a relOp equal to EQ and javax.management.StringValueExp 152 queries.add(Query.eq(Query.attr(stringAttName), 153 Query.value(stringValue))); 154 155 // case 9: 156 // True if an attribute named integerAttName of type Integer has 157 // the value integerValue 158 // We cover javax.management.BinaryRelQueryExp with 159 // a relOp equal to EQ and javax.management.NumericValueExp 160 queries.add(Query.eq(Query.attr(integerAttName), 161 Query.value(integerValue))); 162 163 // case 10: 164 // True if an attribute named primitiveBooleanAttName of type boolean 165 // has the value booleanValue 166 // We cover javax.management.BinaryRelQueryExp with 167 // a relOp equal to EQ and javax.management.BooleanValueExp 168 queries.add(Query.eq(Query.attr(primitiveBooleanAttName), 169 Query.value(booleanValue))); 170 171 // case 11: 172 // True if an attribute named primitiveIntAttName of type int has 173 // not the value smallerIntValue 174 // We cover javax.management.NotQueryExp 175 queries.add(Query.not(Query.eq(Query.attr(primitiveIntAttName), 176 Query.value(smallerIntValue)))); 177 178 // case 12: 179 // True if either 180 // an attribute named primitiveIntAttName of type int has 181 // the value intValue 182 // or 183 // an attribute named primitiveLongAttName of type long has 184 // the value longValue 185 // We cover javax.management.OrQueryExp 186 queries.add(Query.or( 187 Query.eq(Query.attr(primitiveIntAttName), 188 Query.value(intValue)), 189 Query.eq(Query.attr(primitiveLongAttName), 190 Query.value(longValue)))); 191 192 // case 13: 193 // True if 194 // an attribute named primitiveIntAttName of type int has 195 // the value intValue 196 // and 197 // an attribute named primitiveLongAttName of type long has 198 // the value longValue 199 // We cover javax.management.AndQueryExp 200 queries.add(Query.and( 201 Query.eq(Query.attr(primitiveIntAttName), 202 Query.value(intValue)), 203 Query.eq(Query.attr(primitiveLongAttName), 204 Query.value(longValue)))); 205 206 // case 14: 207 // True if an attribute named primitiveIntAttName of type int has 208 // the value intValue 209 // We cover javax.management.InQueryExp 210 ValueExp[] inArray = {Query.value(intValue)}; 211 queries.add(Query.in(Query.attr(primitiveIntAttName), inArray)); 212 213 // case 15: 214 // True if an attribute named primitiveIntAttName of type int has 215 // its value in between smallerIntValue and biggerIntValue 216 // We cover javax.management.BetweenRelQueryExp 217 queries.add(Query.between(Query.attr(primitiveIntAttName), 218 Query.value(smallerIntValue), 219 Query.value(biggerIntValue))); 220 221 // case 16: 222 // True if an attribute named primitiveIntAttName of type int has 223 // a value greater than smallerIntValue 224 // We cover javax.management.BinaryRelQueryExp with 225 // a relOp equal to GT 226 queries.add(Query.gt(Query.attr(primitiveIntAttName), 227 Query.value(smallerIntValue))); 228 229 // case 17: 230 // True if an attribute named primitiveIntAttName of type int has 231 // a value greater or equal to smallerIntValue 232 // We cover javax.management.BinaryRelQueryExp with 233 // a relOp equal to GE 234 queries.add(Query.geq(Query.attr(primitiveIntAttName), 235 Query.value(smallerIntValue))); 236 237 // case 18: 238 // True if an attribute named primitiveIntAttName of type int has 239 // a value smaller than biggerIntValue 240 // We cover javax.management.BinaryRelQueryExp with 241 // a relOp equal to LT 242 queries.add(Query.lt(Query.attr(primitiveIntAttName), 243 Query.value(biggerIntValue))); 244 245 // case 19: 246 // True if an attribute named primitiveIntAttName of type int has 247 // a value smaller or equal to biggerIntValue 248 // We cover javax.management.BinaryRelQueryExp with 249 // a relOp equal to LE 250 queries.add(Query.leq(Query.attr(primitiveIntAttName), 251 Query.value(biggerIntValue))); 252 253 // case 20: 254 // True if an attribute named primitiveIntAttName of type int has 255 // a value equal to intValue minus zero 256 // We cover javax.management.BinaryRelQueryExp with 257 // a relOp equal to MINUS 258 queries.add(Query.eq(Query.attr(primitiveIntAttName), 259 Query.minus(Query.value(intValue), Query.value(0)))); 260 261 // case 21: 262 // True if an attribute named primitiveIntAttName of type int has 263 // a value equal to intValue plus zero 264 // We cover javax.management.BinaryRelQueryExp with 265 // a relOp equal to PLUS 266 queries.add(Query.eq(Query.attr(primitiveIntAttName), 267 Query.plus(Query.value(intValue), Query.value(0)))); 268 269 // case 22: 270 // True if an attribute named primitiveIntAttName of type int has 271 // a value equal to intValue divided by one 272 // We cover javax.management.BinaryRelQueryExp with 273 // a relOp equal to DIV 274 queries.add(Query.eq(Query.attr(primitiveIntAttName), 275 Query.div(Query.value(intValue), Query.value(1)))); 276 277 // case 23: 278 // True if an attribute named primitiveIntAttName of type int has 279 // a value equal to intValue multiplicated by one 280 // We cover javax.management.BinaryRelQueryExp with 281 // a relOp equal to TIMES 282 queries.add(Query.eq(Query.attr(primitiveIntAttName), 283 Query.times(Query.value(intValue), Query.value(1)))); 284 285 // case 24: 286 // That query is a complex one that combines within a big AND 287 // queries with index 2 to 23 inclusive. But because a List is 288 // zero based, we must decrement all indexes by 1 when retrieving 289 // any previously stored query. 290 QueryExp q2_3 = Query.and(queries.get(2-1), queries.get(3-1)); 291 QueryExp q4_5 = Query.and(queries.get(4-1), queries.get(5-1)); 292 QueryExp q6_7 = Query.and(queries.get(6-1), queries.get(7-1)); 293 QueryExp q8_9 = Query.and(queries.get(8-1), queries.get(9-1)); 294 QueryExp q10_11 = Query.and(queries.get(10-1), queries.get(11-1)); 295 QueryExp q12_13 = Query.and(queries.get(12-1), queries.get(13-1)); 296 QueryExp q14_15 = Query.and(queries.get(14-1), queries.get(15-1)); 297 QueryExp q16_17 = Query.and(queries.get(16-1), queries.get(17-1)); 298 QueryExp q18_19 = Query.and(queries.get(18-1), queries.get(19-1)); 299 QueryExp q20_21 = Query.and(queries.get(20-1), queries.get(21-1)); 300 QueryExp q22_23 = Query.and(queries.get(22-1), queries.get(23-1)); 301 QueryExp q2_5 = Query.and(q2_3, q4_5); 302 QueryExp q6_9 = Query.and(q6_7, q8_9); 303 QueryExp q10_13 = Query.and(q10_11, q12_13); 304 QueryExp q14_17 = Query.and(q14_15, q16_17); 305 QueryExp q18_21 = Query.and(q18_19, q20_21); 306 QueryExp q2_9 = Query.and(q2_5, q6_9); 307 QueryExp q10_17 = Query.and(q10_13, q14_17); 308 QueryExp q18_23 = Query.and(q18_21, q22_23); 309 QueryExp q2_17 = Query.and(q2_9, q10_17); 310 queries.add(Query.and(q2_17, q18_23)); 311 312 // case 25: 313 // Complex query mixing AND and OR. 314 queries.add(Query.or(q6_9, q18_23)); 315 } 316 } 317 318 /** 319 * Returns a QueryExp taken is the ArrayList populated by buildQueries(). 320 * Lowest index is 1. 321 * Highest index is returned by getSize(). 322 * <br>The queries numbered 1 to 23 allow to cover all the underlying 323 * Java classes of the JMX API used to build queries. 324 */ 325 public QueryExp getQuery(int index) { 326 return queries.get(index - 1); 327 } 328} 329