001 /*
002 * Copyright 1999-2003 Sun Microsystems, Inc. All Rights Reserved.
003 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
004 *
005 * This code is free software; you can redistribute it and/or modify it
006 * under the terms of the GNU General Public License version 2 only, as
007 * published by the Free Software Foundation. Sun designates this
008 * particular file as subject to the "Classpath" exception as provided
009 * by Sun in the LICENSE file that accompanied this code.
010 *
011 * This code is distributed in the hope that it will be useful, but WITHOUT
012 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
013 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
014 * version 2 for more details (a copy is included in the LICENSE file that
015 * accompanied this code).
016 *
017 * You should have received a copy of the GNU General Public License version
018 * 2 along with this work; if not, write to the Free Software Foundation,
019 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
020 *
021 * Please contact Sun Microsystems, Inc., 4150 Network Circle, Santa Clara,
022 * CA 95054 USA or visit www.sun.com if you need additional information or
023 * have any questions.
024 */
025
026 package javax.naming;
027
028 /**
029 * This is the superclass of all exceptions thrown by
030 * operations in the Context and DirContext interfaces.
031 * The nature of the failure is described by the name of the subclass.
032 * This exception captures the information pinpointing where the operation
033 * failed, such as where resolution last proceeded to.
034 * <ul>
035 * <li> Resolved Name. Portion of name that has been resolved.
036 * <li> Resolved Object. Object to which resolution of name proceeded.
037 * <li> Remaining Name. Portion of name that has not been resolved.
038 * <li> Explanation. Detail explaining why name resolution failed.
039 * <li> Root Exception. The exception that caused this naming exception
040 * to be thrown.
041 *</ul>
042 * null is an acceptable value for any of these fields. When null,
043 * it means that no such information has been recorded for that field.
044 *<p>
045 * A NamingException instance is not synchronized against concurrent
046 * multithreaded access. Multiple threads trying to access and modify
047 * a single NamingException instance should lock the object.
048 *<p>
049 * This exception has been retrofitted to conform to
050 * the general purpose exception-chaining mechanism. The
051 * <i>root exception</i> (or <i>root cause</i>) is the same object as the
052 * <i>cause</i> returned by the {@link Throwable#getCause()} method.
053 *
054 * @author Rosanna Lee
055 * @author Scott Seligman
056 * @version 1.17 07/05/05
057 * @since 1.3
058 */
059
060 public class NamingException extends Exception {
061 /**
062 * Contains the part of the name that has been successfully resolved.
063 * It is a composite name and can be null.
064 * This field is initialized by the constructors.
065 * You should access and manipulate this field
066 * through its get and set methods.
067 * @serial
068 * @see #getResolvedName
069 * @see #setResolvedName
070 */
071 protected Name resolvedName;
072 /**
073 * Contains the object to which resolution of the part of the name was
074 * successful. Can be null.
075 * This field is initialized by the constructors.
076 * You should access and manipulate this field
077 * through its get and set methods.
078 * @serial
079 * @see #getResolvedObj
080 * @see #setResolvedObj
081 */
082 protected Object resolvedObj;
083 /**
084 * Contains the remaining name that has not been resolved yet.
085 * It is a composite name and can be null.
086 * This field is initialized by the constructors.
087 * You should access and manipulate this field
088 * through its get, set, "append" methods.
089 * @serial
090 * @see #getRemainingName
091 * @see #setRemainingName
092 * @see #appendRemainingName
093 * @see #appendRemainingComponent
094 */
095 protected Name remainingName;
096
097 /**
098 * Contains the original exception that caused this NamingException to
099 * 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> does 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> does 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> does 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 };
|