1 /* 2 * Copyright (c) 1999, 2003, 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.naming; 27 28 /** 29 * This is the superclass of all exceptions thrown by 30 * operations in the Context and DirContext interfaces. 31 * The nature of the failure is described by the name of the subclass. 32 * This exception captures the information pinpointing where the operation 33 * failed, such as where resolution last proceeded to. 34 * <ul> 35 * <li> Resolved Name. Portion of name that has been resolved. 36 * <li> Resolved Object. Object to which resolution of name proceeded. 37 * <li> Remaining Name. Portion of name that has not been resolved. 38 * <li> Explanation. Detail explaining why name resolution failed. 39 * <li> Root Exception. The exception that caused this naming exception 40 * to be thrown. 41 *</ul> 42 * null is an acceptable value for any of these fields. When null, 43 * it means that no such information has been recorded for that field. 44 *<p> 45 * A NamingException instance is not synchronized against concurrent 46 * multithreaded access. Multiple threads trying to access and modify 47 * a single NamingException instance should lock the object. 48 *<p> 49 * This exception has been retrofitted to conform to 50 * the general purpose exception-chaining mechanism. The 51 * <i>root exception</i> (or <i>root cause</i>) is the same object as the 52 * <i>cause</i> returned by the {@link Throwable#getCause()} method. 53 * 54 * @author Rosanna Lee 55 * @author Scott Seligman 56 * @since 1.3 57 */ 58 59 60 public class NamingException extends Exception { 61 /** 62 * Contains the part of the name that has been successfully resolved. 63 * It is a composite name and can be null. 64 * This field is initialized by the constructors. 65 * You should access and manipulate this field 66 * through its get and set methods. 67 * @serial 68 * @see #getResolvedName 69 * @see #setResolvedName 70 */ 71 protected Name resolvedName; 72 /** 73 * Contains the object to which resolution of the part of the name was 74 * successful. Can be null. 75 * This field is initialized by the constructors. 76 * You should access and manipulate this field 77 * through its get and set methods. 78 * @serial 79 * @see #getResolvedObj 80 * @see #setResolvedObj 81 */ 82 protected Object resolvedObj; 83 /** 84 * Contains the remaining name that has not been resolved yet. 85 * It is a composite name and can be null. 86 * This field is initialized by the constructors. 87 * You should access and manipulate this field 88 * through its get, set, "append" methods. 89 * @serial 90 * @see #getRemainingName 91 * @see #setRemainingName 92 * @see #appendRemainingName 93 * @see #appendRemainingComponent 94 */ 95 protected Name remainingName; 96 97 /** 98 * Contains the original exception that caused this NamingException to 99 * be thrown. This field is set if there is additional 100 * information that could be obtained from the original 101 * exception, or if the original exception could not be 102 * mapped to a subclass of NamingException. 103 * Can be null. 104 *<p> 105 * This field predates the general-purpose exception chaining facility. 106 * The {@link #initCause(Throwable)} and {@link #getCause()} methods 107 * are now the preferred means of accessing this information. 108 * 109 * @serial 110 * @see #getRootCause 111 * @see #setRootCause(Throwable) 112 * @see #initCause(Throwable) 113 * @see #getCause 114 */ 115 protected Throwable rootException = null; 116 117 /** 118 * Constructs a new NamingException with an explanation. 119 * All unspecified fields are set to null. 120 * 121 * @param explanation A possibly null string containing 122 * additional detail about this exception. 123 * @see java.lang.Throwable#getMessage 124 */ 125 public NamingException(String explanation) { 126 super(explanation); 127 resolvedName = remainingName = null; 128 resolvedObj = null; 129 } 130 131 /** 132 * Constructs a new NamingException. 133 * All fields are set to null. 134 */ 135 public NamingException() { 136 super(); 137 resolvedName = remainingName = null; 138 resolvedObj = null; 139 } 140 141 /** 142 * Retrieves the leading portion of the name that was resolved 143 * successfully. 144 * 145 * @return The part of the name that was resolved successfully. 146 * It is a composite name. It can be null, which means 147 * the resolved name field has not been set. 148 * @see #getResolvedObj 149 * @see #setResolvedName 150 */ 151 public Name getResolvedName() { 152 return resolvedName; 153 } 154 155 /** 156 * Retrieves the remaining unresolved portion of the name. 157 * @return The part of the name that has not been resolved. 158 * It is a composite name. It can be null, which means 159 * the remaining name field has not been set. 160 * @see #setRemainingName 161 * @see #appendRemainingName 162 * @see #appendRemainingComponent 163 */ 164 public Name getRemainingName() { 165 return remainingName; 166 } 167 168 /** 169 * Retrieves the object to which resolution was successful. 170 * This is the object to which the resolved name is bound. 171 * 172 * @return The possibly null object that was resolved so far. 173 * null means that the resolved object field has not been set. 174 * @see #getResolvedName 175 * @see #setResolvedObj 176 */ 177 public Object getResolvedObj() { 178 return resolvedObj; 179 } 180 181 /** 182 * Retrieves the explanation associated with this exception. 183 * 184 * @return The possibly null detail string explaining more 185 * about this exception. If null, it means there is no 186 * detail message for this exception. 187 * 188 * @see java.lang.Throwable#getMessage 189 */ 190 public String getExplanation() { 191 return getMessage(); 192 } 193 194 /** 195 * Sets the resolved name field of this exception. 196 *<p> 197 * <tt>name</tt> is a composite name. If the intent is to set 198 * this field using a compound name or string, you must 199 * "stringify" the compound name, and create a composite 200 * name with a single component using the string. You can then 201 * invoke this method using the resulting composite name. 202 *<p> 203 * A copy of <code>name</code> is made and stored. 204 * Subsequent changes to <code>name</code> do not 205 * affect the copy in this NamingException and vice versa. 206 * 207 * @param name The possibly null name to set resolved name to. 208 * If null, it sets the resolved name field to null. 209 * @see #getResolvedName 210 */ 211 public void setResolvedName(Name name) { 212 if (name != null) 213 resolvedName = (Name)(name.clone()); 214 else 215 resolvedName = null; 216 } 217 218 /** 219 * Sets the remaining name field of this exception. 220 *<p> 221 * <tt>name</tt> is a composite name. If the intent is to set 222 * this field using a compound name or string, you must 223 * "stringify" the compound name, and create a composite 224 * name with a single component using the string. You can then 225 * invoke this method using the resulting composite name. 226 *<p> 227 * A copy of <code>name</code> is made and stored. 228 * Subsequent changes to <code>name</code> do not 229 * affect the copy in this NamingException and vice versa. 230 * @param name The possibly null name to set remaining name to. 231 * If null, it sets the remaining name field to null. 232 * @see #getRemainingName 233 * @see #appendRemainingName 234 * @see #appendRemainingComponent 235 */ 236 public void setRemainingName(Name name) { 237 if (name != null) 238 remainingName = (Name)(name.clone()); 239 else 240 remainingName = null; 241 } 242 243 /** 244 * Sets the resolved object field of this exception. 245 * @param obj The possibly null object to set resolved object to. 246 * If null, the resolved object field is set to null. 247 * @see #getResolvedObj 248 */ 249 public void setResolvedObj(Object obj) { 250 resolvedObj = obj; 251 } 252 253 /** 254 * Add name as the last component in remaining name. 255 * @param name The component to add. 256 * If name is null, this method does not do anything. 257 * @see #setRemainingName 258 * @see #getRemainingName 259 * @see #appendRemainingName 260 */ 261 public void appendRemainingComponent(String name) { 262 if (name != null) { 263 try { 264 if (remainingName == null) { 265 remainingName = new CompositeName(); 266 } 267 remainingName.add(name); 268 } catch (NamingException e) { 269 throw new IllegalArgumentException(e.toString()); 270 } 271 } 272 } 273 274 /** 275 * Add components from 'name' as the last components in 276 * remaining name. 277 *<p> 278 * <tt>name</tt> is a composite name. If the intent is to append 279 * a compound name, you should "stringify" the compound name 280 * then invoke the overloaded form that accepts a String parameter. 281 *<p> 282 * Subsequent changes to <code>name</code> do not 283 * affect the remaining name field in this NamingException and vice versa. 284 * @param name The possibly null name containing ordered components to add. 285 * If name is null, this method does not do anything. 286 * @see #setRemainingName 287 * @see #getRemainingName 288 * @see #appendRemainingComponent 289 */ 290 public void appendRemainingName(Name name) { 291 if (name == null) { 292 return; 293 } 294 if (remainingName != null) { 295 try { 296 remainingName.addAll(name); 297 } catch (NamingException e) { 298 throw new IllegalArgumentException(e.toString()); 299 } 300 } else { 301 remainingName = (Name)(name.clone()); 302 } 303 } 304 305 /** 306 * Retrieves the root cause of this NamingException, if any. 307 * The root cause of a naming exception is used when the service provider 308 * wants to indicate to the caller a non-naming related exception 309 * but at the same time wants to use the NamingException structure 310 * to indicate how far the naming operation proceeded. 311 *<p> 312 * This method predates the general-purpose exception chaining facility. 313 * The {@link #getCause()} method is now the preferred means of obtaining 314 * this information. 315 * 316 * @return The possibly null exception that caused this naming 317 * exception. If null, it means no root cause has been 318 * set for this naming exception. 319 * @see #setRootCause 320 * @see #rootException 321 * @see #getCause 322 */ 323 public Throwable getRootCause() { 324 return rootException; 325 } 326 327 /** 328 * Records the root cause of this NamingException. 329 * If <tt>e</tt> is <tt>this</tt>, this method does not do anything. 330 *<p> 331 * This method predates the general-purpose exception chaining facility. 332 * The {@link #initCause(Throwable)} method is now the preferred means 333 * of recording this information. 334 * 335 * @param e The possibly null exception that caused the naming 336 * operation to fail. If null, it means this naming 337 * exception has no root cause. 338 * @see #getRootCause 339 * @see #rootException 340 * @see #initCause 341 */ 342 public void setRootCause(Throwable e) { 343 if (e != this) { 344 rootException = e; 345 } 346 } 347 348 /** 349 * Returns the cause of this exception. The cause is the 350 * throwable that caused this naming exception to be thrown. 351 * Returns <code>null</code> if the cause is nonexistent or 352 * unknown. 353 * 354 * @return the cause of this exception, or <code>null</code> if the 355 * cause is nonexistent or unknown. 356 * @see #initCause(Throwable) 357 * @since 1.4 358 */ 359 public Throwable getCause() { 360 return getRootCause(); 361 } 362 363 /** 364 * Initializes the cause of this exception to the specified value. 365 * The cause is the throwable that caused this naming exception to be 366 * thrown. 367 *<p> 368 * This method may be called at most once. 369 * 370 * @param cause the cause, which is saved for later retrieval by 371 * the {@link #getCause()} method. A <tt>null</tt> value 372 * indicates that the cause is nonexistent or unknown. 373 * @return a reference to this <code>NamingException</code> instance. 374 * @throws IllegalArgumentException if <code>cause</code> is this 375 * exception. (A throwable cannot be its own cause.) 376 * @throws IllegalStateException if this method has already 377 * been called on this exception. 378 * @see #getCause 379 * @since 1.4 380 */ 381 public Throwable initCause(Throwable cause) { 382 super.initCause(cause); 383 setRootCause(cause); 384 return this; 385 } 386 387 /** 388 * Generates the string representation of this exception. 389 * The string representation consists of this exception's class name, 390 * its detailed message, and if it has a root cause, the string 391 * representation of the root cause exception, followed by 392 * the remaining name (if it is not null). 393 * This string is used for debugging and not meant to be interpreted 394 * programmatically. 395 * 396 * @return The non-null string containing the string representation 397 * of this exception. 398 */ 399 public String toString() { 400 String answer = super.toString(); 401 402 if (rootException != null) { 403 answer += " [Root exception is " + rootException + "]"; 404 } 405 if (remainingName != null) { 406 answer += "; remaining name '" + remainingName + "'"; 407 } 408 return answer; 409 } 410 411 /** 412 * Generates the string representation in more detail. 413 * This string representation consists of the information returned 414 * by the toString() that takes no parameters, plus the string 415 * representation of the resolved object (if it is not null). 416 * This string is used for debugging and not meant to be interpreted 417 * programmatically. 418 * 419 * @param detail If true, include details about the resolved object 420 * in addition to the other information. 421 * @return The non-null string containing the string representation. 422 */ 423 public String toString(boolean detail) { 424 if (!detail || resolvedObj == null) { 425 return toString(); 426 } else { 427 return (toString() + "; resolved object " + resolvedObj); 428 } 429 } 430 431 /** 432 * Use serialVersionUID from JNDI 1.1.1 for interoperability 433 */ 434 private static final long serialVersionUID = -1299181962103167177L; 435 };