1 /*
   2  * Copyright (c) 1999, 2013, 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.  Oracle designates this
   8  * particular file as subject to the "Classpath" exception as provided
   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package javax.management;
  27 
  28 
  29 /**
  30  * <p>Constructs query object constraints.</p>
  31  *
  32  * <p>The MBean Server can be queried for MBeans that meet a particular
  33  * condition, using its {@link MBeanServer#queryNames queryNames} or
  34  * {@link MBeanServer#queryMBeans queryMBeans} method.  The {@link QueryExp}
  35  * parameter to the method can be any implementation of the interface
  36  * {@code QueryExp}, but it is usually best to obtain the {@code QueryExp}
  37  * value by calling the static methods in this class.  This is particularly
  38  * true when querying a remote MBean Server: a custom implementation of the
  39  * {@code QueryExp} interface might not be present in the remote MBean Server,
  40  * but the methods in this class return only standard classes that are
  41  * part of the JMX implementation.</p>
  42  *
  43  * <p>As an example, suppose you wanted to find all MBeans where the {@code
  44  * Enabled} attribute is {@code true} and the {@code Owner} attribute is {@code
  45  * "Duke"}. Here is how you could construct the appropriate {@code QueryExp} by
  46  * chaining together method calls:</p>
  47  *
  48  * <pre>
  49  * QueryExp query =
  50  *     Query.and(Query.eq(Query.attr("Enabled"), Query.value(true)),
  51  *               Query.eq(Query.attr("Owner"), Query.value("Duke")));
  52  * </pre>
  53  *
  54  * @since 1.5
  55  */
  56  public class Query extends Object   {
  57 
  58 
  59      /**
  60       * A code representing the {@link Query#gt} query.  This is chiefly
  61       * of interest for the serialized form of queries.
  62       */
  63      public static final int GT  = 0;
  64 
  65      /**
  66       * A code representing the {@link Query#lt} query.  This is chiefly
  67       * of interest for the serialized form of queries.
  68       */
  69      public static final int LT  = 1;
  70 
  71      /**
  72       * A code representing the {@link Query#geq} query.  This is chiefly
  73       * of interest for the serialized form of queries.
  74       */
  75      public static final int GE  = 2;
  76 
  77      /**
  78       * A code representing the {@link Query#leq} query.  This is chiefly
  79       * of interest for the serialized form of queries.
  80       */
  81      public static final int LE  = 3;
  82 
  83      /**
  84       * A code representing the {@link Query#eq} query.  This is chiefly
  85       * of interest for the serialized form of queries.
  86       */
  87      public static final int EQ  = 4;
  88 
  89 
  90      /**
  91       * A code representing the {@link Query#plus} expression.  This
  92       * is chiefly of interest for the serialized form of queries.
  93       */
  94      public static final int PLUS  = 0;
  95 
  96      /**
  97       * A code representing the {@link Query#minus} expression.  This
  98       * is chiefly of interest for the serialized form of queries.
  99       */
 100      public static final int MINUS = 1;
 101 
 102      /**
 103       * A code representing the {@link Query#times} expression.  This
 104       * is chiefly of interest for the serialized form of queries.
 105       */
 106      public static final int TIMES = 2;
 107 
 108      /**
 109       * A code representing the {@link Query#div} expression.  This is
 110       * chiefly of interest for the serialized form of queries.
 111       */
 112      public static final int DIV   = 3;
 113 
 114 
 115      /**
 116       * Basic constructor.
 117       */
 118      public Query() {
 119      }
 120 
 121 
 122      /**
 123       * Returns a query expression that is the conjunction of two other query
 124       * expressions.
 125       *
 126       * @param q1 A query expression.
 127       * @param q2 Another query expression.
 128       *
 129       * @return  The conjunction of the two arguments.  The returned object
 130       * will be serialized as an instance of the non-public class
 131       * <a href="../../serialized-form.html#javax.management.AndQueryExp">
 132       * javax.management.AndQueryExp</a>.
 133       */
 134      public static QueryExp and(QueryExp q1, QueryExp q2)  {
 135          return new AndQueryExp(q1, q2);
 136      }
 137 
 138      /**
 139       * Returns a query expression that is the disjunction of two other query
 140       * expressions.
 141       *
 142       * @param q1 A query expression.
 143       * @param q2 Another query expression.
 144       *
 145       * @return  The disjunction of the two arguments.  The returned object
 146       * will be serialized as an instance of the non-public class
 147       * <a href="../../serialized-form.html#javax.management.OrQueryExp">
 148       * javax.management.OrQueryExp</a>.
 149       */
 150      public static QueryExp or(QueryExp q1, QueryExp q2)  {
 151          return new OrQueryExp(q1, q2);
 152      }
 153 
 154      /**
 155       * Returns a query expression that represents a "greater than" constraint on
 156       * two values.
 157       *
 158       * @param v1 A value expression.
 159       * @param v2 Another value expression.
 160       *
 161       * @return A "greater than" constraint on the arguments.  The
 162       * returned object will be serialized as an instance of the
 163       * non-public class
 164       * <a href="../../serialized-form.html#javax.management.BinaryRelQueryExp">
 165       * javax.management.BinaryRelQueryExp</a> with a {@code relOp} equal
 166       * to {@link #GT}.
 167       */
 168      public static QueryExp gt(ValueExp v1, ValueExp v2)  {
 169          return new BinaryRelQueryExp(GT, v1, v2);
 170      }
 171 
 172      /**
 173       * Returns a query expression that represents a "greater than or equal
 174       * to" constraint on two values.
 175       *
 176       * @param v1 A value expression.
 177       * @param v2 Another value expression.
 178       *
 179       * @return A "greater than or equal to" constraint on the
 180       * arguments.  The returned object will be serialized as an
 181       * instance of the non-public class
 182       * <a href="../../serialized-form.html#javax.management.BinaryRelQueryExp">
 183       * javax.management.BinaryRelQueryExp</a> with a {@code relOp} equal
 184       * to {@link #GE}.
 185       */
 186      public static QueryExp geq(ValueExp v1, ValueExp v2)  {
 187          return new BinaryRelQueryExp(GE, v1, v2);
 188      }
 189 
 190      /**
 191       * Returns a query expression that represents a "less than or equal to"
 192       * constraint on two values.
 193       *
 194       * @param v1 A value expression.
 195       * @param v2 Another value expression.
 196       *
 197       * @return A "less than or equal to" constraint on the arguments.
 198       * The returned object will be serialized as an instance of the
 199       * non-public class
 200       * <a href="../../serialized-form.html#javax.management.BinaryRelQueryExp">
 201       * javax.management.BinaryRelQueryExp</a> with a {@code relOp} equal
 202       * to {@link #LE}.
 203       */
 204      public static QueryExp leq(ValueExp v1, ValueExp v2)  {
 205          return new BinaryRelQueryExp(LE, v1, v2);
 206      }
 207 
 208      /**
 209       * Returns a query expression that represents a "less than" constraint on
 210       * two values.
 211       *
 212       * @param v1 A value expression.
 213       * @param v2 Another value expression.
 214       *
 215       * @return A "less than" constraint on the arguments.  The
 216       * returned object will be serialized as an instance of the
 217       * non-public class
 218       * <a href="../../serialized-form.html#javax.management.BinaryRelQueryExp">
 219       * javax.management.BinaryRelQueryExp</a> with a {@code relOp} equal
 220       * to {@link #LT}.
 221       */
 222      public static QueryExp lt(ValueExp v1, ValueExp v2)  {
 223          return new BinaryRelQueryExp(LT, v1, v2);
 224      }
 225 
 226      /**
 227       * Returns a query expression that represents an equality constraint on
 228       * two values.
 229       *
 230       * @param v1 A value expression.
 231       * @param v2 Another value expression.
 232       *
 233       * @return A "equal to" constraint on the arguments.  The
 234       * returned object will be serialized as an instance of the
 235       * non-public class
 236       * <a href="../../serialized-form.html#javax.management.BinaryRelQueryExp">
 237       * javax.management.BinaryRelQueryExp</a> with a {@code relOp} equal
 238       * to {@link #EQ}.
 239       */
 240      public static QueryExp eq(ValueExp v1, ValueExp v2)  {
 241          return new BinaryRelQueryExp(EQ, v1, v2);
 242      }
 243 
 244      /**
 245       * Returns a query expression that represents the constraint that one
 246       * value is between two other values.
 247       *
 248       * @param v1 A value expression that is "between" v2 and v3.
 249       * @param v2 Value expression that represents a boundary of the constraint.
 250       * @param v3 Value expression that represents a boundary of the constraint.
 251       *
 252       * @return The constraint that v1 lies between v2 and v3.  The
 253       * returned object will be serialized as an instance of the
 254       * non-public class
 255       * <a href="../../serialized-form.html#javax.management.BetweenQueryExp">
 256       * javax.management.BetweenQueryExp</a>.
 257       */
 258      public static QueryExp between(ValueExp v1, ValueExp v2, ValueExp v3) {
 259          return new BetweenQueryExp(v1, v2, v3);
 260      }
 261 
 262      /**
 263       * Returns a query expression that represents a matching constraint on
 264       * a string argument. The matching syntax is consistent with file globbing:
 265       * supports "<code>?</code>", "<code>*</code>", "<code>[</code>",
 266       * each of which may be escaped with "<code>\</code>";
 267       * character classes may use "<code>!</code>" for negation and
 268       * "<code>-</code>" for range.
 269       * (<code>*</code> for any character sequence,
 270       * <code>?</code> for a single arbitrary character,
 271       * <code>[...]</code> for a character sequence).
 272       * For example: <code>a*b?c</code> would match a string starting
 273       * with the character <code>a</code>, followed
 274       * by any number of characters, followed by a <code>b</code>,
 275       * any single character, and a <code>c</code>.
 276       *
 277       * @param a An attribute expression
 278       * @param s A string value expression representing a matching constraint
 279       *
 280       * @return A query expression that represents the matching
 281       * constraint on the string argument.  The returned object will
 282       * be serialized as an instance of the non-public class
 283       * <a href="../../serialized-form.html#javax.management.MatchQueryExp">
 284       * javax.management.MatchQueryExp</a>.
 285       */
 286      public static QueryExp match(AttributeValueExp a, StringValueExp s)  {
 287          return new MatchQueryExp(a, s);
 288      }
 289 
 290      /**
 291       * <p>Returns a new attribute expression.  See {@link AttributeValueExp}
 292       * for a detailed description of the semantics of the expression.</p>
 293       *
 294       * <p>Evaluating this expression for a given
 295       * <code>objectName</code> includes performing {@link
 296       * MBeanServer#getAttribute MBeanServer.getAttribute(objectName,
 297       * name)}.</p>
 298       *
 299       * @param name The name of the attribute.
 300       *
 301       * @return An attribute expression for the attribute named {@code name}.
 302       */
 303      public static AttributeValueExp attr(String name)  {
 304          return new AttributeValueExp(name);
 305      }
 306 
 307      /**
 308       * <p>Returns a new qualified attribute expression.</p>
 309       *
 310       * <p>Evaluating this expression for a given
 311       * <code>objectName</code> includes performing {@link
 312       * MBeanServer#getObjectInstance
 313       * MBeanServer.getObjectInstance(objectName)} and {@link
 314       * MBeanServer#getAttribute MBeanServer.getAttribute(objectName,
 315       * name)}.</p>
 316       *
 317       * @param className The name of the class possessing the attribute.
 318       * @param name The name of the attribute.
 319       *
 320       * @return An attribute expression for the attribute named name.
 321       * The returned object will be serialized as an instance of the
 322       * non-public class
 323       * <a href="../../serialized-form.html#javax.management.QualifiedAttributeValueExp">
 324       * javax.management.QualifiedAttributeValueExp</a>.
 325       */
 326      public static AttributeValueExp attr(String className, String name)  {
 327          return new QualifiedAttributeValueExp(className, name);
 328      }
 329 
 330      /**
 331       * <p>Returns a new class attribute expression which can be used in any
 332       * Query call that expects a ValueExp.</p>
 333       *
 334       * <p>Evaluating this expression for a given
 335       * <code>objectName</code> includes performing {@link
 336       * MBeanServer#getObjectInstance
 337       * MBeanServer.getObjectInstance(objectName)}.</p>
 338       *
 339       * @return A class attribute expression.  The returned object
 340       * will be serialized as an instance of the non-public class
 341       * <a href="../../serialized-form.html#javax.management.ClassAttributeValueExp">
 342       * javax.management.ClassAttributeValueExp</a>.
 343       */
 344      public static AttributeValueExp classattr()  {
 345          return new ClassAttributeValueExp();
 346      }
 347 
 348      /**
 349       * Returns a constraint that is the negation of its argument.
 350       *
 351       * @param queryExp The constraint to negate.
 352       *
 353       * @return A negated constraint.  The returned object will be
 354       * serialized as an instance of the non-public class
 355       * <a href="../../serialized-form.html#javax.management.NotQueryExp">
 356       * javax.management.NotQueryExp</a>.
 357       */
 358      public static QueryExp not(QueryExp queryExp)  {
 359          return new NotQueryExp(queryExp);
 360      }
 361 
 362      /**
 363       * Returns an expression constraining a value to be one of an explicit list.
 364       *
 365       * @param val A value to be constrained.
 366       * @param valueList An array of ValueExps.
 367       *
 368       * @return A QueryExp that represents the constraint.  The
 369       * returned object will be serialized as an instance of the
 370       * non-public class
 371       * <a href="../../serialized-form.html#javax.management.InQueryExp">
 372       * javax.management.InQueryExp</a>.
 373       */
 374      public static QueryExp in(ValueExp val, ValueExp valueList[])  {
 375          return new InQueryExp(val, valueList);
 376      }
 377 
 378      /**
 379       * Returns a new string expression.
 380       *
 381       * @param val The string value.
 382       *
 383       * @return  A ValueExp object containing the string argument.
 384       */
 385      public static StringValueExp value(String val)  {
 386          return new StringValueExp(val);
 387      }
 388 
 389      /**
 390       * Returns a numeric value expression that can be used in any Query call
 391       * that expects a ValueExp.
 392       *
 393       * @param val An instance of Number.
 394       *
 395       * @return A ValueExp object containing the argument.  The
 396       * returned object will be serialized as an instance of the
 397       * non-public class
 398       * <a href="../../serialized-form.html#javax.management.NumericValueExp">
 399       * javax.management.NumericValueExp</a>.
 400       */
 401      public static ValueExp value(Number val)  {
 402          return new NumericValueExp(val);
 403      }
 404 
 405      /**
 406       * Returns a numeric value expression that can be used in any Query call
 407       * that expects a ValueExp.
 408       *
 409       * @param val An int value.
 410       *
 411       * @return A ValueExp object containing the argument.  The
 412       * returned object will be serialized as an instance of the
 413       * non-public class
 414       * <a href="../../serialized-form.html#javax.management.NumericValueExp">
 415       * javax.management.NumericValueExp</a>.
 416       */
 417      public static ValueExp value(int val)  {
 418          return new NumericValueExp((long) val);
 419      }
 420 
 421      /**
 422       * Returns a numeric value expression that can be used in any Query call
 423       * that expects a ValueExp.
 424       *
 425       * @param val A long value.
 426       *
 427       * @return A ValueExp object containing the argument.  The
 428       * returned object will be serialized as an instance of the
 429       * non-public class
 430       * <a href="../../serialized-form.html#javax.management.NumericValueExp">
 431       * javax.management.NumericValueExp</a>.
 432       */
 433      public static ValueExp value(long val)  {
 434          return new NumericValueExp(val);
 435      }
 436 
 437      /**
 438       * Returns a numeric value expression that can be used in any Query call
 439       * that expects a ValueExp.
 440       *
 441       * @param val A float value.
 442       *
 443       * @return A ValueExp object containing the argument.  The
 444       * returned object will be serialized as an instance of the
 445       * non-public class
 446       * <a href="../../serialized-form.html#javax.management.NumericValueExp">
 447       * javax.management.NumericValueExp</a>.
 448       */
 449      public static ValueExp value(float val)  {
 450          return new NumericValueExp((double) val);
 451      }
 452 
 453      /**
 454       * Returns a numeric value expression that can be used in any Query call
 455       * that expects a ValueExp.
 456       *
 457       * @param val A double value.
 458       *
 459       * @return  A ValueExp object containing the argument.  The
 460       * returned object will be serialized as an instance of the
 461       * non-public class
 462       * <a href="../../serialized-form.html#javax.management.NumericValueExp">
 463       * javax.management.NumericValueExp</a>.
 464       */
 465      public static ValueExp value(double val)  {
 466          return new NumericValueExp(val);
 467      }
 468 
 469      /**
 470       * Returns a boolean value expression that can be used in any Query call
 471       * that expects a ValueExp.
 472       *
 473       * @param val A boolean value.
 474       *
 475       * @return A ValueExp object containing the argument.  The
 476       * returned object will be serialized as an instance of the
 477       * non-public class
 478       * <a href="../../serialized-form.html#javax.management.BooleanValueExp">
 479       * javax.management.BooleanValueExp</a>.
 480       */
 481      public static ValueExp value(boolean val)  {
 482          return new BooleanValueExp(val);
 483      }
 484 
 485      /**
 486       * Returns a binary expression representing the sum of two numeric values,
 487       * or the concatenation of two string values.
 488       *
 489       * @param value1 The first '+' operand.
 490       * @param value2 The second '+' operand.
 491       *
 492       * @return A ValueExp representing the sum or concatenation of
 493       * the two arguments.  The returned object will be serialized as
 494       * an instance of the non-public class
 495       * <a href="../../serialized-form.html#javax.management.BinaryOpValueExp">
 496       * javax.management.BinaryOpValueExp</a> with an {@code op} equal to
 497       * {@link #PLUS}.
 498       */
 499      public static ValueExp plus(ValueExp value1, ValueExp value2) {
 500          return new BinaryOpValueExp(PLUS, value1, value2);
 501      }
 502 
 503      /**
 504       * Returns a binary expression representing the product of two numeric values.
 505       *
 506       *
 507       * @param value1 The first '*' operand.
 508       * @param value2 The second '*' operand.
 509       *
 510       * @return A ValueExp representing the product.  The returned
 511       * object will be serialized as an instance of the non-public
 512       * class
 513       * <a href="../../serialized-form.html#javax.management.BinaryOpValueExp">
 514       * javax.management.BinaryOpValueExp</a> with an {@code op} equal to
 515       * {@link #TIMES}.
 516       */
 517      public static ValueExp times(ValueExp value1,ValueExp value2) {
 518          return new BinaryOpValueExp(TIMES, value1, value2);
 519      }
 520 
 521      /**
 522       * Returns a binary expression representing the difference between two numeric
 523       * values.
 524       *
 525       * @param value1 The first '-' operand.
 526       * @param value2 The second '-' operand.
 527       *
 528       * @return A ValueExp representing the difference between two
 529       * arguments.  The returned object will be serialized as an
 530       * instance of the non-public class
 531       * <a href="../../serialized-form.html#javax.management.BinaryOpValueExp">
 532       * javax.management.BinaryOpValueExp</a> with an {@code op} equal to
 533       * {@link #MINUS}.
 534       */
 535      public static ValueExp minus(ValueExp value1, ValueExp value2) {
 536          return new BinaryOpValueExp(MINUS, value1, value2);
 537      }
 538 
 539      /**
 540       * Returns a binary expression representing the quotient of two numeric
 541       * values.
 542       *
 543       * @param value1 The first '/' operand.
 544       * @param value2 The second '/' operand.
 545       *
 546       * @return A ValueExp representing the quotient of two arguments.
 547       * The returned object will be serialized as an instance of the
 548       * non-public class
 549       * <a href="../../serialized-form.html#javax.management.BinaryOpValueExp">
 550       * javax.management.BinaryOpValueExp</a> with an {@code op} equal to
 551       * {@link #DIV}.
 552       */
 553      public static ValueExp div(ValueExp value1, ValueExp value2) {
 554          return new BinaryOpValueExp(DIV, value1, value2);
 555      }
 556 
 557      /**
 558       * Returns a query expression that represents a matching constraint on
 559       * a string argument. The value must start with the given literal string
 560       * value.
 561       *
 562       * @param a An attribute expression.
 563       * @param s A string value expression representing the beginning of the
 564       * string value.
 565       *
 566       * @return The constraint that a matches s.  The returned object
 567       * will be serialized as an instance of the non-public class
 568       *
 569       * <a href="../../serialized-form.html#javax.management.MatchQueryExp">
 570       * javax.management.MatchQueryExp</a>.
 571       */
 572      public static QueryExp initialSubString(AttributeValueExp a, StringValueExp s)  {
 573          return new MatchQueryExp(a,
 574              new StringValueExp(escapeString(s.getValue()) + "*"));
 575      }
 576 
 577      /**
 578       * Returns a query expression that represents a matching constraint on
 579       * a string argument. The value must contain the given literal string
 580       * value.
 581       *
 582       * @param a An attribute expression.
 583       * @param s A string value expression representing the substring.
 584       *
 585       * @return The constraint that a matches s.  The returned object
 586       * will be serialized as an instance of the non-public class
 587       *
 588       * <a href="../../serialized-form.html#javax.management.MatchQueryExp">
 589       * javax.management.MatchQueryExp</a>.
 590       */
 591      public static QueryExp anySubString(AttributeValueExp a, StringValueExp s) {
 592          return new MatchQueryExp(a,
 593              new StringValueExp("*" + escapeString(s.getValue()) + "*"));
 594      }
 595 
 596      /**
 597       * Returns a query expression that represents a matching constraint on
 598       * a string argument. The value must end with the given literal string
 599       * value.
 600       *
 601       * @param a An attribute expression.
 602       * @param s A string value expression representing the end of the string
 603       * value.
 604       *
 605       * @return The constraint that a matches s.  The returned object
 606       * will be serialized as an instance of the non-public class
 607       *
 608       * <a href="../../serialized-form.html#javax.management.MatchQueryExp">
 609       * javax.management.MatchQueryExp</a>.
 610       */
 611      public static QueryExp finalSubString(AttributeValueExp a, StringValueExp s) {
 612          return new MatchQueryExp(a,
 613              new StringValueExp("*" + escapeString(s.getValue())));
 614      }
 615 
 616      /**
 617       * Returns a query expression that represents an inheritance constraint
 618       * on an MBean class.
 619       * <p>Example: to find MBeans that are instances of
 620       * {@link NotificationBroadcaster}, use
 621       * {@code Query.isInstanceOf(Query.value(NotificationBroadcaster.class.getName()))}.
 622       * </p>
 623       * <p>Evaluating this expression for a given
 624       * <code>objectName</code> includes performing {@link
 625       * MBeanServer#isInstanceOf MBeanServer.isInstanceOf(objectName,
 626       * ((StringValueExp)classNameValue.apply(objectName)).getValue()}.</p>
 627       *
 628       * @param classNameValue The {@link StringValueExp} returning the name
 629       *        of the class of which selected MBeans should be instances.
 630       * @return a query expression that represents an inheritance
 631       * constraint on an MBean class.  The returned object will be
 632       * serialized as an instance of the non-public class
 633       * <a href="../../serialized-form.html#javax.management.InstanceOfQueryExp">
 634       * javax.management.InstanceOfQueryExp</a>.
 635       * @since 1.6
 636       */
 637      public static QueryExp isInstanceOf(StringValueExp classNameValue) {
 638         return new InstanceOfQueryExp(classNameValue);
 639      }
 640 
 641      /**
 642       * Utility method to escape strings used with
 643       * Query.{initial|any|final}SubString() methods.
 644       */
 645      private static String escapeString(String s) {
 646          if (s == null)
 647              return null;
 648          s = s.replace("\\", "\\\\");
 649          s = s.replace("*", "\\*");
 650          s = s.replace("?", "\\?");
 651          s = s.replace("[", "\\[");
 652          return s;
 653      }
 654  }