| 1 7 8 package javax.management; 9 10 11 import java.io.InvalidObjectException ; 13 import java.io.IOException ; 14 import java.io.ObjectInputStream ; 15 import java.io.ObjectOutputStream ; 16 import java.io.ObjectStreamField ; 17 import java.io.Serializable ; 18 import java.security.AccessController ; 19 import java.security.PrivilegedAction ; 20 import java.util.Arrays ; 21 import java.util.Enumeration ; 22 import java.util.HashMap ; 23 import java.util.Hashtable ; 24 25 import com.sun.jmx.mbeanserver.GetPropertyAction; 26 27 158 public class ObjectName implements QueryExp , Serializable { 159 160 164 private final static class Property { 165 166 int _key_index; 167 int _key_length; 168 int _value_length; 169 170 173 Property(int key_index, int key_length, int value_length) { 174 _key_index = key_index; 175 _key_length = key_length; 176 _value_length = value_length; 177 } 178 179 182 void setKeyIndex(int key_index) { 183 _key_index = key_index; 184 } 185 186 189 String getKeyString(String name) { 190 return name.substring(_key_index, _key_index + _key_length); 191 } 192 193 196 String getValueString(String name) { 197 int in_begin = _key_index + _key_length + 1; 198 int out_end = in_begin + _value_length; 199 return name.substring(in_begin, out_end); 200 } 201 } 202 204 205 206 208 209 211 private static final long oldSerialVersionUID = -5467795090068647408L; 218 private static final long newSerialVersionUID = 1081892073854801359L; 221 private static final ObjectStreamField [] oldSerialPersistentFields = 224 { 225 new ObjectStreamField ("domain", String .class), 226 new ObjectStreamField ("propertyList", Hashtable .class), 227 new ObjectStreamField ("propertyListString", String .class), 228 new ObjectStreamField ("canonicalName", String .class), 229 new ObjectStreamField ("pattern", Boolean.TYPE), 230 new ObjectStreamField ("propertyPattern", Boolean.TYPE) 231 }; 232 private static final ObjectStreamField [] newSerialPersistentFields = { }; 235 private static final long serialVersionUID; 238 private static final ObjectStreamField [] serialPersistentFields; 239 private static boolean compat = false; 240 static { 241 try { 242 PrivilegedAction act = new GetPropertyAction("jmx.serial.form"); 243 String form = (String ) AccessController.doPrivileged(act); 244 compat = (form != null && form.equals("1.0")); 245 } catch (Exception e) { 246 } 248 if (compat) { 249 serialPersistentFields = oldSerialPersistentFields; 250 serialVersionUID = oldSerialVersionUID; 251 } else { 252 serialPersistentFields = newSerialPersistentFields; 253 serialVersionUID = newSerialVersionUID; 254 } 255 } 256 257 260 262 265 static final private Property[] _Empty_property_array = new Property[0]; 266 267 270 static final private Hashtable _EmptyPropertyList = new Hashtable (1); 271 272 273 275 277 280 private transient String _canonicalName; 281 282 283 286 private transient Property[] _kp_array; 287 288 291 private transient Property[] _ca_array; 292 293 294 297 private transient int _domain_length = 0; 298 299 300 304 private transient Hashtable _propertyList; 305 306 309 private transient boolean _domain_pattern = false; 310 311 315 private transient boolean _property_pattern = false; 316 317 319 321 322 324 326 337 private void construct(String name) 338 throws MalformedObjectNameException , NullPointerException { 339 340 if (name == null) 342 throw new NullPointerException ("name cannot be null"); 343 344 if (name.length() == 0) { 346 _canonicalName = "*:*"; 348 _kp_array = _Empty_property_array; 349 _ca_array = _Empty_property_array; 350 _domain_length = 1; 351 _propertyList = null; 352 _domain_pattern = true; 353 _property_pattern = true; 354 return; 355 } 356 357 char[] name_chars = name.toCharArray(); 359 int len = name_chars.length; 360 char[] canonical_chars = new char[len]; int cname_index = 0; 363 int index = 0; 364 char c, c1; 365 366 domain_parsing: 368 while (index < len) { 369 switch (c = name_chars[index]) { 370 case ':' : 371 _domain_length = index++; 372 break domain_parsing; 373 case '=' : 374 int i = ++index; 375 while ((i < len) && (name_chars[i++] != ':')) 376 if (i == len) 377 throw new MalformedObjectNameException ( 378 "Domain part must be specified"); 379 break; 380 case '\n' : 381 throw new MalformedObjectNameException ( 382 "Invalid character '\\n' in domain name"); 383 case '*' : 384 case '?' : 385 _domain_pattern = true; 386 default : 387 index++; 388 } 389 } 390 391 if (index == len) 393 throw new MalformedObjectNameException ( 394 "Key properties cannot be empty"); 395 396 System.arraycopy(name_chars, 0, canonical_chars, 0, _domain_length); 398 canonical_chars[_domain_length] = ':'; 399 cname_index = _domain_length + 1; 400 401 Property prop; 403 HashMap keys_map = new HashMap (); 404 String [] keys; 405 String key_name; 406 boolean quoted_value; 407 int property_index = 0; 408 int in_index; 409 int key_index, key_length, value_index, value_length; 410 411 keys = new String [10]; 412 _kp_array = new Property[10]; 413 _property_pattern = false; 414 415 while (index < len) { 416 c = name_chars[index]; 417 418 if (c == '*') { 420 if (_property_pattern) 421 throw new MalformedObjectNameException ( 422 "Cannot have several '*' characters in pattern " + 423 "properties"); 424 else { 425 _property_pattern = true; 426 if ((++index < len ) && (name_chars[index] != ',')) 427 throw new MalformedObjectNameException ( 428 "Invalid character found after '*': end of " + 429 "name or ',' expected"); 430 else if (index == len) { 431 if (property_index == 0) { 432 _kp_array = _Empty_property_array; 434 _ca_array = _Empty_property_array; 435 _propertyList = _EmptyPropertyList; 436 } 437 break; 438 } 439 else { 440 index++; 442 continue; 443 } 444 } 445 } 446 447 in_index = index; 449 key_index = in_index; 450 while ((in_index < len) && ((c1 = name_chars[in_index++]) != '=')) 451 switch (c1) { 452 case '*' : 454 case '?' : 455 case ',' : 456 case ':' : 457 case '\n' : 458 final String ichar = ((c1=='\n')?"\\n":""+c1); 459 throw new MalformedObjectNameException ( 460 "Invalid character '" + ichar + 461 "' in key part of property"); 462 default: ; 463 } 464 if (in_index == len) 465 throw new MalformedObjectNameException ( 466 "Unterminated key property part"); 467 if (in_index == index) 468 throw new MalformedObjectNameException ("Invalid key (empty)"); 469 value_index = in_index; key_length = value_index - key_index - 1; 472 if (name_chars[in_index] == '\"') { 474 quoted_value = true; 475 quoted_value_parsing: 477 while ((++in_index < len) && 478 ((c1 = name_chars[in_index]) != '\"')) { 479 if (c1 == '\\') { 481 if (++in_index == len) 482 throw new MalformedObjectNameException ( 483 "Unterminated quoted value"); 484 switch (c1 = name_chars[in_index]) { 485 case '\\' : 486 case '\"' : 487 case '?' : 488 case '*' : 489 case 'n' : 490 break; default : 492 throw new MalformedObjectNameException ( 493 "Invalid escape sequence '\\" + 494 c1 + "' in quoted value"); 495 } 496 } else if (c1 == '\n') { 497 throw new MalformedObjectNameException ( 498 "Newline in quoted value"); 499 } else { 500 switch (c1) { 501 case '?' : 502 case '*' : 503 throw new MalformedObjectNameException ( 504 "Invalid unescaped reserved character '" + 505 c1 + "' in quoted value"); 506 default: 507 break; 508 } 509 } 510 } 511 if (in_index == len) 512 throw new MalformedObjectNameException ( 513 "Unterminated quoted value"); 514 else value_length = ++in_index - value_index; 515 } 516 else { 517 quoted_value = false; 519 while ((in_index < len) && ((c1 = name_chars[in_index]) != ',')) 520 switch (c1) { 521 case '*' : 523 case '?' : 524 case '=' : 525 case ':' : 526 case '"' : 527 case '\n' : 528 final String ichar = ((c1=='\n')?"\\n":""+c1); 529 throw new MalformedObjectNameException ( 530 "Invalid character '" + c1 + 531 "' in value part of property"); 532 default : in_index++; 533 } 534 value_length = in_index - value_index; 535 } 536 537 if (in_index == len - 1) { 539 if (quoted_value) 540 throw new MalformedObjectNameException ( 541 "Invalid ending character `" + 542 name_chars[in_index] + "'"); 543 else throw new MalformedObjectNameException ( 544 "Invalid ending comma"); 545 } 546 else in_index++; 547 548 prop = new Property(key_index, key_length, value_length); 550 key_name = name.substring(key_index, key_index + key_length); 551 552 if (property_index == keys.length) { 553 String [] tmp_string_array = new String [property_index + 10]; 554 System.arraycopy(keys, 0, tmp_string_array, 0, property_index); 555 keys = tmp_string_array; 556 } 557 keys[property_index] = key_name; 558 559 addProperty(prop, property_index, keys_map, key_name); 560 property_index++; 561 index = in_index; 562 } 563 564 setCanonicalName(name_chars, canonical_chars, keys, 566 keys_map, cname_index, property_index); 567 } 568 569 581 private void construct(String domain, Hashtable props) 582 throws MalformedObjectNameException , NullPointerException { 583 584 if (domain == null) 586 throw new NullPointerException ("domain cannot be null"); 587 588 if (props == null) 590 throw new NullPointerException ("key property list cannot be null"); 591 592 if (props.isEmpty()) 594 throw new MalformedObjectNameException ( 595 "key property list cannot be empty"); 596 597 if (!isDomain(domain)) 599 throw new MalformedObjectNameException ("Invalid domain: " + domain); 600 601 final StringBuffer sb = new StringBuffer (); 603 sb.append(domain).append(':'); 604 _domain_length = domain.length(); 605 606 int nb_props = props.size(); 608 _kp_array = new Property[nb_props]; 609 610 String [] keys = new String [nb_props]; 611 final Enumeration e = props.keys(); 612 final HashMap keys_map = new HashMap (); 613 Property prop; 614 int key_index; 615 for (int i = 0; e.hasMoreElements(); i++ ) { 616 if (i > 0) sb.append(","); 617 String key = ""; 618 try { 619 key = (String )e.nextElement(); 620 } catch (Exception x) { 621 throw new MalformedObjectNameException ("Invalid key `" + 622 key + "'"); 623 } 624 String value = ""; 625 try { 626 value = (String )props.get(key); 627 } catch (Exception x) { 628 throw new MalformedObjectNameException ("Invalid value `" + 629 value + "'"); 630 } 631 key_index = sb.length(); 632 checkKey(key); 633 sb.append(key); 634 keys[i] = key; 635 sb.append("="); 636 checkValue(value); 637 sb.append(value); 638 prop = new Property(key_index, key.length(), value.length()); 639 addProperty(prop, i, keys_map, key); 640 } 641 642 int len = sb.length(); 644 char[] initial_chars = new char[len]; 645 sb.getChars(0, len, initial_chars, 0); 646 char[] canonical_chars = new char[len]; 647 System.arraycopy(initial_chars, 0, canonical_chars, 0, 648 _domain_length + 1); 649 setCanonicalName(initial_chars, canonical_chars, keys, keys_map, 650 _domain_length + 1, _kp_array.length); 651 } 652 654 656 660 private void addProperty(Property prop, int index, 661 HashMap keys_map, String key_name) 662 throws MalformedObjectNameException { 663 664 if (keys_map.containsKey(key_name)) throw new 665 MalformedObjectNameException ("key `" + 666 key_name +"' already defined"); 667 668 if (index == _kp_array.length) { 670 Property[] tmp_prop_array = new Property[index + 10]; 671 System.arraycopy(_kp_array, 0, tmp_prop_array, 0, index); 672 _kp_array = tmp_prop_array; 673 } 674 _kp_array[index] = prop; 675 keys_map.put(key_name, prop); 676 } 677 678 683 private void setCanonicalName(char[] specified_chars, 684 char[] canonical_chars, 685 String [] keys, HashMap keys_map, 686 int prop_index, int nb_props) { 687 688 if (_kp_array != _Empty_property_array) { 690 String [] tmp_keys = new String [nb_props]; 691 Property[] tmp_props = new Property[nb_props]; 692 693 System.arraycopy(keys, 0, tmp_keys, 0, nb_props); 694 Arrays.sort(tmp_keys); 695 keys = tmp_keys; 696 System.arraycopy(_kp_array, 0, tmp_props, 0 , nb_props); 697 _kp_array = tmp_props; 698 _ca_array = new Property[nb_props]; 699 700 for (int i = 0; i < nb_props; i++) 703 _ca_array[i] = (Property) keys_map.get(keys[i]); 704 705 int last_index = nb_props - 1; 708 int prop_len; 709 Property prop; 710 for (int i = 0; i <= last_index; i++) { 711 prop = _ca_array[i]; 712 prop_len = prop._key_length + prop._value_length + 1; 714 System.arraycopy(specified_chars, prop._key_index, 715 canonical_chars, prop_index, prop_len); 716 prop.setKeyIndex(prop_index); 717 prop_index += prop_len; 718 if (i != last_index) { 719 canonical_chars[prop_index] = ','; 720 prop_index++; 721 } 722 } 723 } 724 725 if (_property_pattern) { 727 if (_kp_array != _Empty_property_array) 728 canonical_chars[prop_index++] = ','; 729 canonical_chars[prop_index++] = '*'; 730 } 731 732 _canonicalName = (new String (canonical_chars, 0, prop_index)).intern(); 734 } 735 736 746 private final static int parseKey(final char[] s, final int startKey) 747 throws MalformedObjectNameException { 748 int next = startKey; 749 int endKey = startKey; 750 final int len = s.length; 751 while (next < len) { 752 final char k = s[next++]; 753 switch (k) { 754 case '*': 755 case '?': 756 case ',': 757 case ':': 758 case '\n': 759 final String ichar = ((k=='\n')?"\\n":""+k); 760 throw new 761 MalformedObjectNameException ("Invalid character in key: `" 762 + ichar + "'"); 763 case '=': 764 endKey = next-1; 766 break; 767 default: 768 if (next < len) continue; 769 else endKey=next; 770 } 771 break; 772 } 773 return endKey; 774 } 775 776 786 private final static int parseValue(final char[] s, final int startValue) 787 throws MalformedObjectNameException { 788 789 int next = startValue; 790 int endValue = startValue; 791 792 final int len = s.length; 793 final char q=s[startValue]; 794 795 if (q == '"') { 796 if (++next == len) throw new 798 &n
|