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