1 // 2 // Copyright (c) ZeroC, Inc. All rights reserved. 3 // 4 5 package Ice; 6 7 /** 8 * Utility methods for the Ice run time. 9 **/ 10 public final class Util 11 { 12 /** 13 * Creates a new empty property set. 14 * 15 * @return A new empty property set. 16 **/ 17 public static Properties createProperties()18 createProperties() 19 { 20 return new PropertiesI(); 21 } 22 23 /** 24 * Creates a property set initialized from an argument vector. 25 * 26 * @param args A command-line argument vector, possibly containing 27 * options to set properties. If the command-line options include 28 * a <code>--Ice.Config</code> option, the corresponding configuration 29 * files are parsed. If the same property is set in a configuration 30 * file and in the argument vector, the argument vector takes precedence. 31 * <p> 32 * This method modifies the argument vector by removing any Ice-related options. 33 * 34 * @return A property set initialized with the property settings 35 * that were removed from <code>args</code>. 36 **/ 37 public static Properties createProperties(StringSeqHolder args)38 createProperties(StringSeqHolder args) 39 { 40 return new PropertiesI(args, null); 41 } 42 43 /** 44 * Creates a property set initialized from an argument vector. 45 * 46 * @param args A command-line argument vector, possibly containing 47 * options to set properties. If the command-line options include 48 * a <code>--Ice.Config</code> option, the corresponding configuration 49 * files are parsed. If the same property is set in a configuration 50 * file and in the argument vector, the argument vector takes precedence. 51 * <p> 52 * This method modifies the argument vector by removing any Ice-related options. 53 * @param defaults Default values for the property set. Settings in configuration 54 * files and <code>args</code> override these defaults. 55 * 56 * @return An initalized property set. 57 **/ 58 public static Properties createProperties(StringSeqHolder args, Properties defaults)59 createProperties(StringSeqHolder args, Properties defaults) 60 { 61 return new PropertiesI(args, defaults); 62 } 63 64 /** 65 * Creates a property set initialized from an argument vector. 66 * 67 * @param args A command-line argument vector, possibly containing 68 * options to set properties. If the command-line options include 69 * a <code>--Ice.Config</code> option, the corresponding configuration 70 * files are parsed. If the same property is set in a configuration 71 * file and in the argument vector, the argument vector takes precedence. 72 * 73 * @return A property set initialized with the property settings 74 * in <code>args</code>. 75 **/ 76 public static Properties createProperties(String[] args)77 createProperties(String[] args) 78 { 79 StringSeqHolder argsH = new StringSeqHolder(args); 80 return createProperties(argsH); 81 } 82 83 /** 84 * Creates a property set initialized from an argument vector. 85 * 86 * @param args A command-line argument vector, possibly containing 87 * options to set properties. If the command-line options include 88 * a <code>--Ice.Config</code> option, the corresponding configuration 89 * files are parsed. If the same property is set in a configuration 90 * file and in the argument vector, the argument vector takes precedence. 91 * @param defaults Default values for the property set. Settings in configuration 92 * files and <code>args</code> override these defaults. 93 * 94 * @return An initalized property set. 95 **/ 96 public static Properties createProperties(String[] args, Properties defaults)97 createProperties(String[] args, Properties defaults) 98 { 99 StringSeqHolder argsH = new StringSeqHolder(args); 100 return createProperties(argsH, defaults); 101 } 102 103 /** 104 * Creates a communicator. 105 * 106 * @param args A command-line argument vector. Any Ice-related options 107 * in this vector are used to intialize the communicator. 108 * This method modifies the argument vector by removing any Ice-related options. 109 * 110 * @return The initialized communicator. 111 **/ 112 public static Communicator initialize(StringSeqHolder args)113 initialize(StringSeqHolder args) 114 { 115 return initialize(args, (InitializationData)null); 116 } 117 118 /** 119 * Creates a communicator. 120 * 121 * @param args A command-line argument vector. Any Ice-related options 122 * in this vector are used to intialize the communicator. 123 * 124 * @return The initialized communicator. 125 **/ 126 public static Communicator initialize(String[] args)127 initialize(String[] args) 128 { 129 StringSeqHolder argsH = new StringSeqHolder(args); 130 return initialize(argsH); 131 } 132 133 /** 134 * Creates a communicator. 135 * 136 * @param args A command-line argument vector. Any Ice-related options 137 * in this vector are used to intialize the communicator. 138 * This method modifies the argument vector by removing any Ice-related options. 139 * 140 * @param initData Additional intialization data. Property settings in <code>args</code> 141 * override property settings in <code>initData</code>. 142 * 143 * @return The initialized communicator. 144 * 145 * @see InitializationData 146 **/ 147 public static Communicator initialize(StringSeqHolder args, InitializationData initData)148 initialize(StringSeqHolder args, InitializationData initData) 149 { 150 if(initData == null) 151 { 152 initData = new InitializationData(); 153 } 154 else 155 { 156 initData = initData.clone(); 157 } 158 initData.properties = createProperties(args, initData.properties); 159 160 CommunicatorI result = new CommunicatorI(initData); 161 result.finishSetup(args); 162 return result; 163 } 164 165 /** 166 * Creates a communicator. 167 * 168 * @param args A command-line argument vector. Any Ice-related options 169 * in this vector are used to intialize the communicator. 170 * This method modifies the argument vector by removing any Ice-related options. 171 * 172 * @param configFile Path to a config file that sets the new communicator's default 173 * properties. 174 * 175 * @return The initialized communicator. 176 **/ 177 public static Communicator initialize(StringSeqHolder args, String configFile)178 initialize(StringSeqHolder args, String configFile) 179 { 180 InitializationData initData = null; 181 if(configFile != null) 182 { 183 initData = new InitializationData(); 184 initData.properties = Util.createProperties(); 185 initData.properties.load(configFile); 186 } 187 188 return initialize(args, initData); 189 } 190 191 /** 192 * Creates a communicator. 193 * 194 * @param args A command-line argument vector. Any Ice-related options 195 * in this vector are used to intialize the communicator. 196 * 197 * @param initData Additional intialization data. Property settings in <code>args</code> 198 * override property settings in <code>initData</code>. 199 * 200 * @return The initialized communicator. 201 * 202 * @see InitializationData 203 **/ 204 public static Communicator initialize(String[] args, InitializationData initData)205 initialize(String[] args, InitializationData initData) 206 { 207 StringSeqHolder argsH = new StringSeqHolder(args); 208 return initialize(argsH, initData); 209 } 210 211 /** 212 * Creates a communicator. 213 * 214 * @param args A command-line argument vector. Any Ice-related options 215 * in this vector are used to intialize the communicator. 216 * 217 * @param configFile Path to a config file that sets the new communicator's default 218 * properties. 219 * 220 * @return The initialized communicator. 221 * 222 * @see InitializationData 223 **/ 224 public static Communicator initialize(String[] args, String configFile)225 initialize(String[] args, String configFile) 226 { 227 StringSeqHolder argsH = new StringSeqHolder(args); 228 return initialize(argsH, configFile); 229 } 230 231 /** 232 * Creates a communicator. 233 * 234 * @param initData Additional intialization data. 235 * 236 * @return The initialized communicator. 237 * 238 * @see InitializationData 239 **/ 240 public static Communicator initialize(InitializationData initData)241 initialize(InitializationData initData) 242 { 243 if(initData == null) 244 { 245 initData = new InitializationData(); 246 } 247 else 248 { 249 initData = initData.clone(); 250 } 251 252 CommunicatorI result = new CommunicatorI(initData); 253 result.finishSetup(new StringSeqHolder(new String[0])); 254 return result; 255 } 256 257 /** 258 * Creates a communicator. 259 * 260 * @param configFile Path to a config file that sets the new communicator's default 261 * properties. 262 * 263 * @return The initialized communicator. 264 **/ 265 public static Communicator initialize(String configFile)266 initialize(String configFile) 267 { 268 InitializationData initData = null; 269 if(configFile != null) 270 { 271 initData = new InitializationData(); 272 initData.properties = Util.createProperties(); 273 initData.properties.load(configFile); 274 } 275 276 return initialize(initData); 277 } 278 279 /** 280 * Creates a communicator using a default configuration. 281 * 282 * @return A new communicator instance. 283 **/ 284 public static Communicator initialize()285 initialize() 286 { 287 return initialize(new InitializationData()); 288 } 289 290 /** 291 * Converts a string to an object identity. 292 * 293 * @param s The string to convert. 294 * 295 * @return The converted object identity. 296 **/ 297 public static Identity stringToIdentity(String s)298 stringToIdentity(String s) 299 { 300 Identity ident = new Identity(); 301 302 // 303 // Find unescaped separator; note that the string may contain an escaped 304 // backslash before the separator. 305 // 306 int slash = -1, pos = 0; 307 while((pos = s.indexOf('/', pos)) != -1) 308 { 309 int escapes = 0; 310 while(pos - escapes > 0 && s.charAt(pos - escapes - 1) == '\\') 311 { 312 escapes++; 313 } 314 315 // 316 // We ignore escaped escapes 317 // 318 if(escapes % 2 == 0) 319 { 320 if(slash == -1) 321 { 322 slash = pos; 323 } 324 else 325 { 326 // 327 // Extra unescaped slash found. 328 // 329 IdentityParseException ex = new IdentityParseException(); 330 ex.str = "unescaped backslash in identity `" + s + "'"; 331 throw ex; 332 } 333 } 334 pos++; 335 } 336 337 if(slash == -1) 338 { 339 ident.category = ""; 340 try 341 { 342 ident.name = IceUtilInternal.StringUtil.unescapeString(s, 0, s.length(), "/"); 343 } 344 catch(IllegalArgumentException e) 345 { 346 IdentityParseException ex = new IdentityParseException(); 347 ex.str = "invalid identity name `" + s + "': " + e.getMessage(); 348 throw ex; 349 } 350 } 351 else 352 { 353 try 354 { 355 ident.category = IceUtilInternal.StringUtil.unescapeString(s, 0, slash, "/"); 356 } 357 catch(IllegalArgumentException e) 358 { 359 IdentityParseException ex = new IdentityParseException(); 360 ex.str = "invalid category in identity `" + s + "': " + e.getMessage(); 361 throw ex; 362 } 363 if(slash + 1 < s.length()) 364 { 365 try 366 { 367 ident.name = IceUtilInternal.StringUtil.unescapeString(s, slash + 1, s.length(), "/"); 368 } 369 catch(IllegalArgumentException e) 370 { 371 IdentityParseException ex = new IdentityParseException(); 372 ex.str = "invalid name in identity `" + s + "': " + e.getMessage(); 373 throw ex; 374 } 375 } 376 else 377 { 378 ident.name = ""; 379 } 380 } 381 382 return ident; 383 } 384 385 /** 386 * Converts an object identity to a string. 387 * 388 * @param ident The object identity to convert. 389 * 390 * @param toStringMode Specifies if and how non-printable ASCII characters are escaped in the result. 391 * 392 * @return The string representation of the object identity. 393 **/ identityToString(Identity ident, ToStringMode toStringMode)394 public static String identityToString(Identity ident, ToStringMode toStringMode) 395 { 396 if(ident.category == null || ident.category.length() == 0) 397 { 398 return IceUtilInternal.StringUtil.escapeString(ident.name, "/", toStringMode); 399 } 400 else 401 { 402 return IceUtilInternal.StringUtil.escapeString(ident.category, "/", toStringMode) + '/' + 403 IceUtilInternal.StringUtil.escapeString(ident.name, "/", toStringMode); 404 } 405 } 406 407 /** 408 * Converts an object identity to a string. 409 * 410 * @param ident The object identity to convert. 411 * 412 * @return The string representation of the object identity using the default mode (Unicode) 413 **/ identityToString(Identity ident)414 public static String identityToString(Identity ident) 415 { 416 return identityToString(ident, ToStringMode.Unicode); 417 } 418 419 /** 420 * Compares the object identities of two proxies. 421 * 422 * @param lhs A proxy. 423 * @param rhs A proxy. 424 * @return -1 if the identity in <code>lhs</code> compares 425 * less than the identity in <code>rhs</code>; 0 if the identities 426 * compare equal; 1, otherwise. 427 * 428 * @see ProxyIdentityKey 429 * @see ProxyIdentityFacetKey 430 * @see #proxyIdentityAndFacetCompare 431 **/ 432 public static int proxyIdentityCompare(ObjectPrx lhs, ObjectPrx rhs)433 proxyIdentityCompare(ObjectPrx lhs, ObjectPrx rhs) 434 { 435 if(lhs == null && rhs == null) 436 { 437 return 0; 438 } 439 else if(lhs == null && rhs != null) 440 { 441 return -1; 442 } 443 else if(lhs != null && rhs == null) 444 { 445 return 1; 446 } 447 else 448 { 449 Identity lhsIdentity = lhs.ice_getIdentity(); 450 Identity rhsIdentity = rhs.ice_getIdentity(); 451 int n; 452 if((n = lhsIdentity.name.compareTo(rhsIdentity.name)) != 0) 453 { 454 return n; 455 } 456 return lhsIdentity.category.compareTo(rhsIdentity.category); 457 } 458 } 459 460 /** 461 * Compares the object identities and facets of two proxies. 462 * 463 * @param lhs A proxy. 464 * @param rhs A proxy. 465 * @return -1 if the identity and facet in <code>lhs</code> compare 466 * less than the identity and facet in <code>rhs</code>; 0 if the identities 467 * and facets compare equal; 1, otherwise. 468 * 469 * @see ProxyIdentityFacetKey 470 * @see ProxyIdentityKey 471 * @see #proxyIdentityCompare 472 **/ 473 public static int proxyIdentityAndFacetCompare(ObjectPrx lhs, ObjectPrx rhs)474 proxyIdentityAndFacetCompare(ObjectPrx lhs, ObjectPrx rhs) 475 { 476 if(lhs == null && rhs == null) 477 { 478 return 0; 479 } 480 else if(lhs == null && rhs != null) 481 { 482 return -1; 483 } 484 else if(lhs != null && rhs == null) 485 { 486 return 1; 487 } 488 else 489 { 490 Identity lhsIdentity = lhs.ice_getIdentity(); 491 Identity rhsIdentity = rhs.ice_getIdentity(); 492 int n; 493 if((n = lhsIdentity.name.compareTo(rhsIdentity.name)) != 0) 494 { 495 return n; 496 } 497 if((n = lhsIdentity.category.compareTo(rhsIdentity.category)) != 0) 498 { 499 return n; 500 } 501 502 String lhsFacet = lhs.ice_getFacet(); 503 String rhsFacet = rhs.ice_getFacet(); 504 if(lhsFacet == null && rhsFacet == null) 505 { 506 return 0; 507 } 508 else if(lhsFacet == null) 509 { 510 return -1; 511 } 512 else if(rhsFacet == null) 513 { 514 return 1; 515 } 516 return lhsFacet.compareTo(rhsFacet); 517 } 518 } 519 520 /** 521 * Returns the process-wide logger. 522 * 523 * @return The process-wide logger. 524 **/ 525 public static Logger getProcessLogger()526 getProcessLogger() 527 { 528 synchronized(_processLoggerMutex) 529 { 530 if(_processLogger == null) 531 { 532 // 533 // TODO: Would be nice to be able to use process name as prefix by default. 534 // 535 _processLogger = new LoggerI("", ""); 536 } 537 538 return _processLogger; 539 } 540 } 541 542 /** 543 * Changes the process-wide logger. 544 * 545 * @param logger The new process-wide logger. 546 **/ 547 public static void setProcessLogger(Logger logger)548 setProcessLogger(Logger logger) 549 { 550 synchronized(_processLoggerMutex) 551 { 552 _processLogger = logger; 553 } 554 } 555 556 /** 557 * Returns the Ice version in the form <code>A.B.C</code>, where <code>A</code> indicates the 558 * major version, <code>B</code> indicates the minor version, and <code>C</code> indicates the 559 * patch level. 560 * 561 * @return The Ice version. 562 **/ 563 public static String stringVersion()564 stringVersion() 565 { 566 return "3.7.2"; // "A.B.C", with A=major, B=minor, C=patch 567 } 568 569 /** 570 * Returns the Ice version as an integer in the form <code>A.BB.CC</code>, where <code>A</code> 571 * indicates the major version, <code>BB</code> indicates the minor version, and <code>CC</code> 572 * indicates the patch level. For example, for Ice 3.3.1, the returned value is 30301. 573 * 574 * @return The Ice version. 575 **/ 576 public static int intVersion()577 intVersion() 578 { 579 return 30702; // AABBCC, with AA=major, BB=minor, CC=patch 580 } 581 582 /** 583 * Converts a string to a protocol version. 584 * 585 * @param version The string to convert. 586 * 587 * @return The converted protocol version. 588 **/ 589 static public Ice.ProtocolVersion stringToProtocolVersion(String version)590 stringToProtocolVersion(String version) 591 { 592 return new Ice.ProtocolVersion(stringToMajor(version), stringToMinor(version)); 593 } 594 595 /** 596 * Converts a string to an encoding version. 597 * 598 * @param version The string to convert. 599 * 600 * @return The converted object identity. 601 **/ 602 static public Ice.EncodingVersion stringToEncodingVersion(String version)603 stringToEncodingVersion(String version) 604 { 605 return new Ice.EncodingVersion(stringToMajor(version), stringToMinor(version)); 606 } 607 608 /** 609 * Converts a protocol version to a string. 610 * 611 * @param v The protocol version to convert. 612 * 613 * @return The converted string. 614 **/ 615 static public String protocolVersionToString(Ice.ProtocolVersion v)616 protocolVersionToString(Ice.ProtocolVersion v) 617 { 618 return majorMinorToString(v.major, v.minor); 619 } 620 621 /** 622 * Converts an encoding version to a string. 623 * 624 * @param v The encoding version to convert. 625 * 626 * @return The converted string. 627 **/ 628 static public String encodingVersionToString(Ice.EncodingVersion v)629 encodingVersionToString(Ice.EncodingVersion v) 630 { 631 return majorMinorToString(v.major, v.minor); 632 } 633 634 /** 635 * Returns the supported Ice protocol version. 636 * 637 * @return The Ice protocol version. 638 **/ 639 static public Ice.ProtocolVersion currentProtocol()640 currentProtocol() 641 { 642 return IceInternal.Protocol.currentProtocol.clone(); 643 } 644 645 /** 646 * Returns the supported Ice encoding version. 647 * 648 * @return The Ice encoding version. 649 **/ 650 static public Ice.EncodingVersion currentEncoding()651 currentEncoding() 652 { 653 return IceInternal.Protocol.currentEncoding.clone(); 654 } 655 656 /** 657 * Translates a Slice type id to a Java class name. 658 * 659 * @param id The Slice type id, such as <code>::Module::Type</code>. 660 * @return The equivalent Java class name, or null if the type id is malformed. 661 **/ typeIdToClass(String id)662 public static String typeIdToClass(String id) 663 { 664 if(!id.startsWith("::")) 665 { 666 return null; 667 } 668 669 StringBuilder buf = new StringBuilder(id.length()); 670 671 int start = 2; 672 boolean done = false; 673 while(!done) 674 { 675 int end = id.indexOf(':', start); 676 String s; 677 if(end != -1) 678 { 679 s = id.substring(start, end); 680 start = end + 2; 681 } 682 else 683 { 684 s = id.substring(start); 685 done = true; 686 } 687 if(buf.length() > 0) 688 { 689 buf.append('.'); 690 } 691 buf.append(fixKwd(s)); 692 } 693 694 return buf.toString(); 695 } 696 fixKwd(String name)697 private static String fixKwd(String name) 698 { 699 // 700 // Keyword list. *Must* be kept in alphabetical order. Note that checkedCast and uncheckedCast 701 // are not Java keywords, but are in this list to prevent illegal code being generated if 702 // someone defines Slice operations with that name. 703 // 704 final String[] keywordList = 705 { 706 "abstract", "assert", "boolean", "break", "byte", "case", "catch", 707 "char", "checkedCast", "class", "clone", "const", "continue", "default", "do", 708 "double", "else", "enum", "equals", "extends", "false", "final", "finalize", 709 "finally", "float", "for", "getClass", "goto", "hashCode", "if", 710 "implements", "import", "instanceof", "int", "interface", "long", 711 "native", "new", "notify", "notifyAll", "null", "package", "private", 712 "protected", "public", "return", "short", "static", "strictfp", "super", "switch", 713 "synchronized", "this", "throw", "throws", "toString", "transient", 714 "true", "try", "uncheckedCast", "void", "volatile", "wait", "while" 715 }; 716 boolean found = java.util.Arrays.binarySearch(keywordList, name) >= 0; 717 return found ? "_" + name : name; 718 } 719 720 static private byte stringToMajor(String str)721 stringToMajor(String str) 722 { 723 int pos = str.indexOf('.'); 724 if(pos == -1) 725 { 726 throw new Ice.VersionParseException("malformed version value `" + str + "'"); 727 } 728 729 String majStr = str.substring(0, pos); 730 int majVersion; 731 try 732 { 733 majVersion = Integer.parseInt(majStr); 734 } 735 catch(NumberFormatException ex) 736 { 737 throw new Ice.VersionParseException("invalid version value `" + str + "'"); 738 } 739 740 if(majVersion < 1 || majVersion > 255) 741 { 742 throw new Ice.VersionParseException("range error in version `" + str + "'"); 743 } 744 745 return (byte)majVersion; 746 } 747 748 static private byte stringToMinor(String str)749 stringToMinor(String str) 750 { 751 int pos = str.indexOf('.'); 752 if(pos == -1) 753 { 754 throw new Ice.VersionParseException("malformed version value `" + str + "'"); 755 } 756 757 String minStr = str.substring(pos + 1, str.length()); 758 int minVersion; 759 try 760 { 761 minVersion = Integer.parseInt(minStr); 762 } 763 catch(NumberFormatException ex) 764 { 765 throw new Ice.VersionParseException("invalid version value `" + str + "'"); 766 } 767 768 if(minVersion < 0 || minVersion > 255) 769 { 770 throw new Ice.VersionParseException("range error in version `" + str + "'"); 771 } 772 773 return (byte)minVersion; 774 } 775 776 static private String majorMinorToString(byte major, byte minor)777 majorMinorToString(byte major, byte minor) 778 { 779 StringBuilder str = new StringBuilder(); 780 str.append(major < 0 ? major + 255 : (int)major); 781 str.append("."); 782 str.append(minor < 0 ? minor + 255 : (int)minor); 783 return str.toString(); 784 } 785 786 public final static Ice.ProtocolVersion Protocol_1_0 = new Ice.ProtocolVersion((byte)1, (byte)0); 787 788 public final static Ice.EncodingVersion Encoding_1_0 = new Ice.EncodingVersion((byte)1, (byte)0); 789 public final static Ice.EncodingVersion Encoding_1_1 = new Ice.EncodingVersion((byte)1, (byte)1); 790 791 private static java.lang.Object _processLoggerMutex = new java.lang.Object(); 792 private static Logger _processLogger = null; 793 } 794