Frames | No Frames |
1: /* GiopNamingServiceURLContext.java -- handles corbaname: urls 2: Copyright (C) 2006 Free Software Foundation, Inc. 3: 4: This file is part of GNU Classpath. 5: 6: GNU Classpath is free software; you can redistribute it and/or modify 7: it under the terms of the GNU General Public License as published by 8: the Free Software Foundation; either version 2, or (at your option) 9: any later version. 10: 11: GNU Classpath is distributed in the hope that it will be useful, but 12: WITHOUT ANY WARRANTY; without even the implied warranty of 13: MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU 14: General Public License for more details. 15: 16: You should have received a copy of the GNU General Public License 17: along with GNU Classpath; see the file COPYING. If not, write to the 18: Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 19: 02110-1301 USA. 20: 21: Linking this library statically or dynamically with other modules is 22: making a combined work based on this library. Thus, the terms and 23: conditions of the GNU General Public License cover the whole 24: combination. 25: 26: As a special exception, the copyright holders of this library give you 27: permission to link this library with independent modules to produce an 28: executable, regardless of the license terms of these independent 29: modules, and to copy and distribute the resulting executable under 30: terms of your choice, provided that you also meet, for each linked 31: independent module, the terms and conditions of the license of that 32: module. An independent module is a module which is not derived from 33: or based on this library. If you modify this library, you may extend 34: this exception to your version of the library, but you are not 35: obligated to do so. If you do not wish to do so, delete this 36: exception statement from your version. */ 37: 38: 39: package gnu.javax.naming.giop; 40: 41: import gnu.CORBA.NamingService.Ext; 42: import gnu.CORBA.NamingService.NameTransformer; 43: 44: import java.util.Hashtable; 45: 46: import javax.naming.Binding; 47: import javax.naming.Context; 48: import javax.naming.ContextNotEmptyException; 49: import javax.naming.InvalidNameException; 50: import javax.naming.Name; 51: import javax.naming.NameAlreadyBoundException; 52: import javax.naming.NameClassPair; 53: import javax.naming.NameNotFoundException; 54: import javax.naming.NameParser; 55: import javax.naming.NamingEnumeration; 56: import javax.naming.NamingException; 57: import javax.naming.OperationNotSupportedException; 58: import javax.naming.directory.InvalidAttributesException; 59: 60: import org.omg.CORBA.ORB; 61: import org.omg.CORBA.portable.Delegate; 62: import org.omg.CORBA.portable.ObjectImpl; 63: import org.omg.CosNaming.BindingIteratorHolder; 64: import org.omg.CosNaming.BindingListHolder; 65: import org.omg.CosNaming.NameComponent; 66: import org.omg.CosNaming.NamingContext; 67: import org.omg.CosNaming.NamingContextExt; 68: import org.omg.CosNaming.NamingContextExtHelper; 69: import org.omg.CosNaming.NamingContextHelper; 70: import org.omg.CosNaming._NamingContextExtStub; 71: import org.omg.CosNaming._NamingContextStub; 72: import org.omg.CosNaming.NamingContextPackage.AlreadyBound; 73: import org.omg.CosNaming.NamingContextPackage.CannotProceed; 74: import org.omg.CosNaming.NamingContextPackage.InvalidName; 75: import org.omg.CosNaming.NamingContextPackage.NotFound; 76: 77: /** 78: * The context to represent the corba naming service. Being the naming service, 79: * the returned context supports creating the subcontexts, forwarding this task 80: * to the existing naming service. When listing bindings, it uses the 81: * {@link Context#BATCHSIZE} property to determine, how many bindings should 82: * be returned at once (the process is transparend) 83: * 84: * @author Audrius Meskauskas (audriusa@Bioinformatics.org) 85: */ 86: public class GiopNamingServiceURLContext extends CorbalocParser implements 87: Context 88: { 89: /** 90: * This number of bindings will be requested from the naming server at once, 91: * while the subsequent bindings will be requested via binding iterator one by 92: * one. Use {@link Context#BATCHSIZE} to override the value of this constant. 93: */ 94: public int DEFAULT_BATCH_SIZE = 20; 95: 96: /** 97: * The object request broker, used to access the naming service. This field 98: * is only initialised when the context is constructed from the URL. 99: */ 100: ORB orb; 101: 102: /** 103: * The properties. 104: */ 105: Hashtable properties; 106: 107: /** 108: * The parent factory. 109: */ 110: GiopNamingServiceFactory factory; 111: 112: /** 113: * The name transformer to obtain the name from its string representation. The 114: * to_name method of the naming service is avoided as it may be remote and 115: * hence expensive. The conversion rules are standard and cannot be service 116: * specific. 117: */ 118: static NameTransformer transformer = new NameTransformer(); 119: 120: /** 121: * The batch size for list operations - how many to return at once. 122: */ 123: public final int howMany; 124: 125: /** 126: * Creates a new naming context that uses naming service, represented by the 127: * given CORBA object. 128: * 129: * @param props 130: * the environment table. 131: * @param aFactory 132: * parent factory. This reference is used during cleanup. 133: * @param anOrb 134: * the associated ORB. This reference is used during cleanup. 135: */ 136: public GiopNamingServiceURLContext(Hashtable props, 137: GiopNamingServiceFactory aFactory, 138: ORB anOrb) 139: { 140: factory = aFactory; 141: orb = anOrb; 142: 143: properties = props; 144: howMany = getBatchSize(); 145: } 146: 147: public NamingContextExt getService(String address) 148: { 149: org.omg.CORBA.Object nsObject = orb.string_to_object(address); 150: Delegate delegate = ((ObjectImpl) nsObject)._get_delegate(); 151: 152: // If the IOR provides the IDL ID, we can check if our name 153: // service is old NamingContext or new NamingContextExt. 154: // Not all forms of the URL always provide the IDL id. 155: if (!nsObject._is_a(NamingContextExtHelper.id()) 156: && nsObject._is_a(NamingContextHelper.id())) 157: { 158: // We are surely working with the old version. 159: _NamingContextStub stub = new _NamingContextStub(); 160: stub._set_delegate(delegate); 161: // The Ext object will add the necessary extensions. 162: return new Ext(stub); 163: } 164: else 165: { 166: // We expecte the service to be the NamingContextExt (this is true 167: // for both Sun's and our implementations). There is no easy way 168: // to check the version. 169: _NamingContextExtStub stub = new _NamingContextExtStub(); 170: stub._set_delegate(delegate); 171: return stub; 172: } 173: } 174: 175: /** 176: * Split the corbaname name into the address of the naming service (first 177: * part) and the name of the object in the naming service (second part) 178: */ 179: public String[] split(String corbaloc) throws InvalidNameException 180: { 181: if (corbaloc.endsWith("#")) 182: corbaloc = corbaloc.substring(0, corbaloc.length() - 1); 183: 184: // No name part - parse as corbaname. 185: if (corbaloc.indexOf('#') < 0) 186: { 187: if (!corbaloc.regionMatches(true, 0, pxCORBANAME, 0, 188: pxCORBANAME.length())) 189: throw new InvalidNameException(corbaloc + " must start with " 190: + pxCORBANAME); 191: corbaloc = pxCORBALOC + corbaloc.substring(pxCORBANAME.length()); 192: return new String[] { corbaloc, "" }; 193: } 194: 195: return corbaloc(corbaloc, orb); 196: } 197: 198: /** 199: * Give the specified name for the specified object. The passed name must not 200: * be already bound to some other object. The components of the name are 201: * mapped into the components of the CORBA name. 202: * 203: * @param name 204: * the name that will be given to the object (in the scope of this 205: * context). 206: * @param obj 207: * the object being named. 208: * @throws NameAlreadyBoundException 209: * if this name is already used to name some object. 210: * @throws InvalidAttributesException 211: * if the object does not supply all required attributes. 212: * @throws NamingException 213: * if the naming operation has failed due other reasons. 214: */ 215: public void bind(Name name, Object obj) throws NamingException 216: { 217: bind(name.toString(), obj); 218: } 219: 220: /** 221: * Give the specified name for the specified object. The passed name must not 222: * be already bound to some other object. 223: * 224: * @param name 225: * the name that will be given to the object (in the scope of this 226: * context). 227: * @param obj 228: * the object being named. 229: * @throws NameAlreadyBoundException 230: * if this name is already used to name some object. 231: * @throws InvalidAttributesException 232: * if the object does not supply all required attributes. 233: * @throws NamingException 234: * if the naming operation has failed due other reasons. 235: */ 236: public void bind(String name, Object obj) throws NamingException 237: { 238: try 239: { 240: String[] n = split(name); 241: org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj; 242: getService(n[0]).bind(transformer.toName(n[1]), object); 243: } 244: catch (ClassCastException e) 245: { 246: throw new NamingException(org.omg.CORBA.Object.class + " required "); 247: } 248: catch (InvalidName e) 249: { 250: throw new InvalidNameException(); 251: } 252: catch (AlreadyBound e) 253: { 254: throw new NameAlreadyBoundException(); 255: } 256: catch (Exception e) 257: { 258: throw new NamingException(e.toString()); 259: } 260: } 261: 262: /** 263: * Releases all resources, associated with this context. The close() method 264: * can be called several times, but after it has been once invoked, it is not 265: * allowed to call any other method of this context. This method destroys 266: * the ORB, if we have one. 267: * 268: * @throws NamingException 269: */ 270: public void close() throws NamingException 271: { 272: if (orb != null && factory != null) 273: { 274: factory.checkIfReferenced(orb); 275: } 276: } 277: 278: /** 279: * Not supported. 280: */ 281: public Name composeName(Name name, Name prefix) throws NamingException 282: { 283: throw new OperationNotSupportedException(); 284: } 285: 286: /** 287: * Not supported 288: */ 289: public String composeName(String name1, String name2) throws NamingException 290: { 291: throw new OperationNotSupportedException(); 292: } 293: 294: /** 295: * Creates the new naming subcontext and binds it to the current (this) 296: * context. The returned object will wrap around the newly created CORBA 297: * subcontext 298: * 299: * @param subContext 300: * the name of the new context being created 301: * @return the newly created context, bound to the instance of the context on 302: * that the method has been called 303: * @throws NameAlreadyBoundException 304: * if this name is already bound 305: * @throws InvalidAttributesException 306: * if the creation of the new context requires the missing mandatory 307: * attributes 308: * @throws NamingException 309: */ 310: public Context createSubcontext(Name subContext) throws NamingException 311: { 312: return createSubcontext(subContext.toString()); 313: } 314: 315: /** 316: * Creates the new naming subcontext and binds it to the current (this) 317: * context. The returned object will wrap around the newly created CORBA 318: * subcontext 319: * 320: * @param subContext 321: * the name of the new context being created 322: * @return the newly created context, bound to the instance of the context on 323: * that the method has been called 324: * @throws NameAlreadyBoundException 325: * if this name is already bound 326: * @throws InvalidAttributesException 327: * if the creation of the new context requires the missing mandatory 328: * attributes 329: * @throws NamingException 330: */ 331: public Context createSubcontext(String subContext) throws NamingException 332: { 333: try 334: { 335: String[] n = split(subContext); 336: org.omg.CORBA.Object subcontext = getService(n[0]).bind_new_context( 337: transformer.toName(n[1])); 338: Hashtable clonedProps = new Hashtable(); 339: clonedProps.putAll(properties); 340: 341: // Nulls are passed both for orb and factory, as the child contexts 342: // need not to do any cleanup. 343: return new ContextContinuation(subcontext, clonedProps, null, null); 344: } 345: catch (AlreadyBound e) 346: { 347: throw new NameAlreadyBoundException(subContext); 348: } 349: catch (InvalidName e) 350: { 351: throw new InvalidNameException(subContext); 352: } 353: catch (Exception ex) 354: { 355: throw new NamingException(ex.toString()); 356: } 357: } 358: 359: /** 360: * Removes the naming subcontext from this naming context. Returns without 361: * action if such subcontext does not exist. The context being destroyed must 362: * be empty. 363: * 364: * @param subContext 365: * the name of the subcontext beig removed. 366: * @throws ContextNotEmptyException 367: * if the named context is not empty. 368: * @throws NamingException 369: */ 370: public void destroySubcontext(Name subContext) throws NamingException 371: { 372: unbind(subContext); 373: } 374: 375: /** 376: * Removes the naming subcontext from this naming context. Returns without 377: * action if such subcontext does not exist. The context being destroyed must 378: * be empty. 379: * 380: * @param subContext 381: * the name of the subcontext beig removed. 382: * @throws ContextNotEmptyException 383: * if the named context is not empty. 384: * @throws NamingException 385: */ 386: public void destroySubcontext(String subContext) throws NamingException 387: { 388: unbind(subContext); 389: } 390: 391: /** 392: * Returs the empty string. 393: */ 394: public String getNameInNamespace() throws NamingException 395: { 396: return ""; 397: } 398: 399: /** 400: * Not supported. 401: */ 402: public NameParser getNameParser(Name name) throws NamingException 403: { 404: throw new UnsupportedOperationException(); 405: } 406: 407: /** 408: * Not supported. 409: */ 410: public NameParser getNameParser(String name) throws NamingException 411: { 412: throw new UnsupportedOperationException(); 413: } 414: 415: /** 416: * Creates and returns the enumeration over the name bindings that are present 417: * the given subcontext. The enumeration elements have the type of 418: * {@link NameClassPair}, providing also information about the class of the 419: * bound object. The behaviour in the case if the bindings are added or 420: * removed later is not defined. The contents of the subcontexts are not 421: * included. 422: * 423: * @param name 424: * the name of the subcontext 425: * @return the enumeration over the names, known for the given subcontext. 426: * @throws NamingException 427: */ 428: public NamingEnumeration list(Name name) throws NamingException 429: { 430: return list(name.toString()); 431: } 432: 433: /** 434: * Creates and returns the enumeration over the name bindings that are present 435: * the given subcontext. The enumeration elements have the type of 436: * {@link NameClassPair}, providing also information about the class of the 437: * bound object. The behaviour in the case if the bindings are added or 438: * removed later is not defined. The contents of the subcontexts are not 439: * included. 440: * 441: * @param name 442: * the name of the subcontext 443: * @return the enumeration over the names, known for the given subcontext. 444: * @throws NamingException 445: */ 446: public NamingEnumeration list(String name) throws NamingException 447: { 448: BindingIteratorHolder bi = new BindingIteratorHolder(); 449: BindingListHolder bl = new BindingListHolder(); 450: 451: NamingContext subcontext; 452: 453: String [] n = split(name); 454: NamingContextExt service = getService(n[0]); 455: 456: if (n[1].length() == 0) 457: subcontext = service; 458: else 459: { 460: try 461: { 462: subcontext = (NamingContextHelper.narrow(service.resolve_str(n[1]))); 463: } 464: catch (Exception e) 465: { 466: throw new NamingException(e.toString()); 467: } 468: 469: } 470: 471: subcontext.list(howMany, bl, bi); 472: 473: return new ListEnumeration(bl, bi, howMany); 474: } 475: 476: /** 477: * Creates and returns the enumeration over the name - object bindings that 478: * are present the given subcontext. The enumeration elements have the type of 479: * {@link Binding}, providing also information about the class of the bound 480: * object. The behaviour in the case if the bindings are added or removed 481: * later is not defined. The contents of the subcontexts are not included. 482: * 483: * @param name 484: * the name of the subcontext 485: * @return the enumeration over the names, known for the given subcontext. 486: * @throws NamingException 487: */ 488: public NamingEnumeration listBindings(Name name) throws NamingException 489: { 490: return listBindings(name.toString()); 491: } 492: 493: /** 494: * Creates and returns the enumeration over the name - object bindings that 495: * are present the given subcontext. The enumeration elements have the type of 496: * {@link Binding}, providing also information about the class of the bound 497: * object. The behaviour in the case if the bindings are added or removed 498: * later is not defined. The contents of the subcontexts are not included. 499: * 500: * @param name 501: * the name of the subcontext 502: * @return the enumeration over the names, known for the given subcontext. 503: * @throws NamingException 504: */ 505: public NamingEnumeration listBindings(String name) throws NamingException 506: { 507: BindingIteratorHolder bi = new BindingIteratorHolder(); 508: BindingListHolder bl = new BindingListHolder(); 509: 510: NamingContext subcontext; 511: 512: String [] n = split(name); 513: NamingContextExt service = getService(n[0]); 514: 515: if (n[1].length() == 0) 516: subcontext = service; 517: else 518: { 519: try 520: { 521: subcontext = (NamingContextHelper.narrow(service.resolve_str(n[1]))); 522: } 523: catch (Exception e) 524: { 525: throw new NamingException(e.toString()); 526: } 527: 528: } 529: 530: subcontext.list(howMany, bl, bi); 531: 532: return new ListBindingsEnumeration(bl, bi, howMany, subcontext); 533: } 534: 535: /** 536: * Gets the previously named object by name. If the passed name is empty, the 537: * method should return a cloned instance of this naming context. 538: * 539: * @param name 540: * the name of the object being searched in this context 541: * @return the named object 542: * @throws NameNotFoundException 543: * if the name is not found 544: */ 545: public Object lookup(Name name) throws NamingException 546: { 547: return lookup(name.toString()); 548: } 549: 550: /** 551: * Gets the previously named object by name. If the passed name is empty, the 552: * method should return a cloned instance of this naming context. 553: * 554: * @param name 555: * the name of the object being searched in this context 556: * @return the named object 557: * @throws NamingException 558: * if the naming fails. 559: */ 560: public Object lookup(String name) throws NamingException 561: { 562: try 563: { 564: String [] n = split(name); 565: NamingContextExt service = getService(n[0]); 566: return service.resolve_str(n[1]); 567: } 568: catch (NotFound e) 569: { 570: throw new NameNotFoundException(); 571: } 572: catch (InvalidName e) 573: { 574: throw new InvalidNameException(); 575: } 576: catch (Exception e) 577: { 578: throw new NamingException(e.toString()); 579: } 580: } 581: 582: /** 583: * Not supported. 584: */ 585: public Object lookupLink(Name name) throws NamingException 586: { 587: throw new OperationNotSupportedException(); 588: } 589: 590: /** 591: * Not supported. 592: */ 593: public Object lookupLink(String name) throws NamingException 594: { 595: throw new OperationNotSupportedException(); 596: } 597: 598: /** 599: * Give the specified name for the specified object. Unlike bind, this method 600: * silently replaces the existing binding for this name, if one exists. 601: * 602: * @param name 603: * the name that will be given to the object (in the scope of this 604: * context). 605: * @param obj 606: * the object being named. 607: * @throws InvalidAttributesException 608: * if the object does not supply all required attributes. 609: * @throws NamingException 610: * if the naming operation has failed due other reasons. 611: */ 612: public void rebind(Name name, Object obj) throws NamingException 613: { 614: rebind(name.toString(), obj); 615: } 616: 617: /** 618: * Give the specified name for the specified object. Unlike bind, this method 619: * silently replaces the existing binding for this name, if one exists. 620: * 621: * @param name 622: * the name that will be given to the object (in the scope of this 623: * context). 624: * @param obj 625: * the object being named. 626: * @throws InvalidAttributesException 627: * if the object does not supply all required attributes. 628: * @throws NamingException 629: * if the naming operation has failed due other reasons. 630: */ 631: public void rebind(String name, Object obj) throws NamingException 632: { 633: try 634: { 635: String[] n = split(name); 636: NamingContextExt service = getService(n[0]); 637: 638: org.omg.CORBA.Object object = (org.omg.CORBA.Object) obj; 639: service.rebind(transformer.toName(n[1]), object); 640: } 641: catch (ClassCastException e) 642: { 643: throw new NamingException(org.omg.CORBA.Object.class + " required "); 644: } 645: catch (InvalidName e) 646: { 647: throw new InvalidNameException(); 648: } 649: catch (Exception e) 650: { 651: throw new NamingException(e.toString()); 652: } 653: } 654: 655: /** 656: * Renames the existing binding, removing the existing and giving the new name 657: * for the same object. 658: * 659: * @param oldName 660: * the existing name of the known object 661: * @param newName 662: * the new name of the same object 663: * @throws NameNotFoundException 664: * if the oldName is unknown for this context 665: * @throws NamingException 666: * if the naming operation has failed due other reasons. 667: */ 668: public void rename(Name oldName, Name newName) throws NamingException 669: { 670: Object object = lookup(oldName); 671: unbind(oldName); 672: bind(newName, object); 673: } 674: 675: /** 676: * Renames the existing binding, removing the existing and giving the new name 677: * for the same object. 678: * 679: * @param oldName 680: * the existing name of the known object 681: * @param newName 682: * the new name of the same object 683: * @throws NameNotFoundException 684: * if the oldName is unknown for this context 685: * @throws NamingException 686: * if the naming operation has failed due other reasons. 687: */ 688: public void rename(String oldName, String newName) throws NamingException 689: { 690: Object object = lookup(oldName); 691: unbind(oldName); 692: bind(newName, object); 693: } 694: 695: /** 696: * Removes the name - object mapping from the current context. This method 697: * returns without action if the name is not bound to an object in the 698: * terminal context, but throws {@link NameNotFoundException} if one of the 699: * intermadiate contexts does not exist. 700: * 701: * @param name 702: * the name to be removed 703: * @throws NameNotFoundException 704: * if one of the intermediate naming contexts does not exist. Will 705: * not be thrown if just the terminal binding is missing. 706: * @throws NamingException 707: * if the naming operation has failed due other reasons. 708: */ 709: public void unbind(Name name) throws NamingException 710: { 711: unbind(name.toString()); 712: } 713: 714: /** 715: * Removes the name - object mapping from the current context. This method 716: * returns without action if the name is not bound to an object in the 717: * terminal context, but throws {@link NameNotFoundException} if one of the 718: * intermadiate contexts does not exist. 719: * 720: * @param name 721: * the name to be removed 722: * @throws NameNotFoundException 723: * if one of the intermediate naming contexts does not exist. Will 724: * not be thrown if just the terminal binding is missing. 725: * @throws NamingException 726: * if the naming operation has failed due other reasons. 727: */ 728: public void unbind(String name) throws NamingException 729: { 730: try 731: { 732: String[] n = split(name); 733: NamingContextExt service = getService(n[0]); 734: 735: service.unbind(transformer.toName(n[1])); 736: } 737: catch (NotFound e) 738: { 739: throw new NameNotFoundException(name); 740: } 741: catch (CannotProceed e) 742: { 743: throw new ContextNotEmptyException(name); 744: } 745: catch (InvalidName e) 746: { 747: throw new InvalidNameException(name); 748: } 749: } 750: 751: /** 752: * Add new environment property to the environment of this context. Both name 753: * and value of the new property must not be null. If the property is already 754: * defined, is current value is replaced by the propVal. 755: * 756: * @param key 757: * the name of the new property 758: * @param value 759: * the value of the new property 760: * @return the previous value of this property or null if the property has not 761: * been previously defined 762: * @throws NamingException 763: */ 764: public Object addToEnvironment(String key, Object value) 765: throws NamingException 766: { 767: if (key == null || value == null) 768: throw new NullPointerException(); 769: return properties.put(key, value); 770: } 771: 772: /** 773: * Returns the environment, associated with this naming context. The returned 774: * table should never be modified by the caller. Use {@link #addToEnvironment} 775: * and {@link #removeFromEnvironment} to modify the environement, if needed. 776: * 777: * @return the table, representing the environment of this context 778: * @throws NamingException 779: */ 780: public Hashtable getEnvironment() throws NamingException 781: { 782: return properties; 783: } 784: 785: /** 786: * Removes the property with the given name from the environment. Returns 787: * without action if this property is not defined. 788: * 789: * @param propName 790: * the name of the property being removed. 791: * @return the value of the property that has been removed or null if the 792: * property was not defined. 793: * @throws NamingException 794: */ 795: public Object removeFromEnvironment(String propName) throws NamingException 796: { 797: return properties.remove(propName); 798: } 799: 800: /** 801: * Convert the {@link Name} into array of the name components, required to the 802: * CORBA naming service. First the string representation is obtained, then 803: * it is converted using parsing rules of the CORBA name. 804: * 805: * @param name 806: * then name to convert 807: * @return the converted array of components. 808: */ 809: public NameComponent[] toGiop(Name name) throws InvalidName 810: { 811: return transformer.toName(name.toString()); 812: } 813: 814: /** 815: * Get the batch size from the environment properties. The batch size is used 816: * for listing operations. 817: * 818: * @return the batch size, or some default value if not specified. 819: */ 820: public int getBatchSize() 821: { 822: int batchSize = DEFAULT_BATCH_SIZE; 823: Object bs = properties.get(Context.BATCHSIZE); 824: if (bs != null) 825: { 826: try 827: { 828: int b = Integer.parseInt(bs.toString()); 829: if (b >= 0) 830: batchSize = b; 831: } 832: catch (NumberFormatException e) 833: { 834: // OK, use default value. 835: } 836: } 837: return batchSize; 838: } 839: 840: }