001/*
002 * IBM and/or HCL Confidential
003 * OCO Source Materials
004 * (C) Copyright IBM Corp 2006, 2015.  All Rights Reserved.
005 * (C) Copyright HCL Technologies Ltd. 2016, 2018.  All Rights Reserved.
006 *
007 * The source code for this program is not published or otherwise
008 * divested of its trade secrets, irrespective of what has been
009 * deposited with the U.S. Copyright Office.
010 */
011
012package com.ibm.rational.wvcm.stp;
013
014import javax.wvcm.Feedback;
015import javax.wvcm.Resource;
016import javax.wvcm.WvcmException;
017
018import com.ibm.rational.wvcm.stpex.StpExEnumeration;
019import com.ibm.rational.wvcm.stpex.annotation.RpcEnum;
020
021/**
022 * An extension of {@link javax.wvcm.WvcmException javax.wvcm.WvcmException}
023 * used throughout this API. Although API methods are declared to throw
024 * WvcmException, the exception actually thrown is StpException or one of its
025 * subclasses.
026 * <p>
027 * This class extends the WvcmException class, adding a <i>sub-reason code</i>
028 * field that encodes conditions specific to this API more finely than the
029 * {@link javax.wvcm.WvcmException.ReasonCode}
030 * <p>
031 * This class (unlike the WvcmException class) leverages the Java 1.4 chained
032 * exception mechanism. By default, if an StpException is constructed from one
033 * or more nested Throwables, the first nested Throwable in the list is also set
034 * as the StpException's {@link java.lang.Throwable#initCause cause}. In
035 * certain special cases, the cause may be set to something other than the first
036 * nested Throwable.
037 * 
038 * Exception classes that extend StpException because they convey additional
039 * information, are as follows:
040 * <ul>
041 * <li>{@link StpPropertyException} - adds name of property responsible for the
042 * exception
043 * <p>
044 * <li>{@link StpPartialResultsException} - holds a ResourceList of child
045 * resources successfully received, a nested list of Exceptions for child
046 * resources that could not be retrieved, and an indicator of whether the two
047 * lists completely identify all resources that were supposed to be retrieved.
048 * <p>
049 * </ul>
050 */
051public abstract class StpException extends WvcmException
052{
053    /**
054     * The specification for the data implementation object associated with this
055     * exception.
056     */
057    public interface Data {
058        public String getMessage();
059        public StpReasonCode getStpReasonCode();
060        public String toString();
061    }
062
063    /**
064     * An encoding of exception conditions specific to this API. Each
065     * StpReasonCode maps to one WvcmException.ReasonCode, but, because the
066     * granularity of the StpReasonCode enumeration is finer than that of the
067     * ReasonCode, the mapping may be many-to-one.
068     * <p>
069     * 
070     * When the correspondence between an StpReasonCode and a ReasonCode is not
071     * obvious, the StpReasonCode is mapped to either ReasonCode.CONFLICT or 
072     * ReasonCode.FORBIDDEN 
073     * using the following rationale:
074     * <p>
075     * <ul>
076     * <li>{@link javax.wvcm.WvcmException.ReasonCode#CONFLICT CONFLICT} - the exception
077     * relates to an issue where the client may be able to retry the method
078     * after changing the state on some object.
079     * 
080     * <li>{@link javax.wvcm.WvcmException.ReasonCode#FORBIDDEN FORBIDDEN} - the
081     * exception relates to an issue where the client cannot do anything to
082     * retry the method.
083     * </ul>
084     * 
085     * For conditions where there is not enough information to decide whether or
086     * not there is anything the client could do to retry the method, the
087     * StpReasonCode is classified as CONFLICT.
088     * <p>
089     */
090
091    public static enum StpReasonCode implements StpExEnumeration
092    {
093        /**
094         * The request timed out waiting for a resource to become free.
095         */
096        @RpcEnum(id=72)
097        REQUEST_TIMED_OUT(ReasonCode.ABORTED),
098
099        /**
100         * <code>Precondition:</code> Cannot create this resource at the
101         * specified location.
102         */
103        @RpcEnum(id=7)
104        CANNOT_CREATE_AT_THIS_LOCATION,
105
106        /**
107         * <code>Precondition:</code> Operation failed because it attempted to
108         * set a protected property.
109         */
110        @RpcEnum(id=9)
111        CANNOT_MODIFY_PROTECTED_PROPERTY,
112        
113        /** Cannot overwrite existing binding. */
114        @RpcEnum(id=10)
115        CANNOT_OVERWRITE,
116
117        /**
118         * The operation cannot be performed because of a conflict with resource
119         * state.
120         */
121        @RpcEnum(id=17)
122        CONFLICT,
123
124        /**
125         * A checkout was attempted with no explicit activity and no current
126         * activity in the workspace.
127         */
128        @RpcEnum(id=0)
129        ACTIVITY_NEEDED(ReasonCode.CONFLICT),
130
131        /**
132         * The specified record is already being edited (by the same user).
133         */
134        @RpcEnum(id=1)
135        ALREADY_BEING_EDITED(ReasonCode.CONFLICT),
136
137        /**
138         * Authentication information is required but client didn't provide any.
139         */
140        @RpcEnum(id=2)
141        AUTHENTICATION_INFO_REQUIRED(ReasonCode.CONFLICT),
142
143        /**
144         * The requested action is inappropriate for the current state of the
145         * query (precondition failure)
146         */
147        @RpcEnum(id=5)
148        BAD_SOURCE_STATE(ReasonCode.CONFLICT),
149
150        /**
151         * The checkin operation failed because the resource is not checked out.
152         */
153        @RpcEnum(id=6)
154        CANNOT_CHECKIN_MUST_BE_CHECKED_OUT(ReasonCode.CONFLICT),
155
156        /**
157         * Used when a string is not supported by the server's operating system.
158         */
159        @RpcEnum(id=8)
160        CANNOT_ENCODE_STRING(ReasonCode.CONFLICT),
161
162        /**
163         * The uncheckout operation failed because the resource is not checked
164         * out.
165         */
166        @RpcEnum(id=11)
167        CANNOT_UNCHECKOUT_MUST_BE_CHECKED_OUT(ReasonCode.CONFLICT),
168
169        /**
170         * Checkout failed because the branch was not mastered locally.
171         */
172        @RpcEnum(id=86)
173        CHECKOUT_BRANCH_NOT_MASTERED(ReasonCode.CONFLICT),
174        
175        /**
176         * Checkout failed because the branch type was not mastered locally.
177         */
178        @RpcEnum(id=87)
179        CHECKOUT_BRTYPE_NOT_MASTERED(ReasonCode.CONFLICT),
180        
181        /** Version being checked out is not the latest  **/
182        @RpcEnum(id=12)
183        CHECKOUT_NOT_LATEST(ReasonCode.CONFLICT),
184
185        /** The client location is not within a file area */
186        @RpcEnum(id=15)
187        CLIENT_LOCATION_NOT_IN_FILE_AREA(ReasonCode.CONFLICT),
188
189        /** A communication precondition failed */
190        @RpcEnum(id=16)
191        CONDITIONAL_EXECUTION(ReasonCode.CONFLICT),
192
193        /**
194         * An operation failed because the connection to the remote server could
195         * not be established or terminated prematurely after being established.
196         */
197        @RpcEnum(id=18)
198        CONNECTION_FAILED(ReasonCode.CONFLICT),
199
200        /**
201         * A deliver operation failed because selected activities depend on
202         * un-delivered activities.
203         */
204        @RpcEnum(id=90)
205        DELIVER_INVALID_ACTIVITIES(ReasonCode.CONFLICT),
206        
207        /**
208         * An attempt to deliver a resource from the change context to the
209         * database failed.
210         */
211        @RpcEnum(id=20)
212        DELIVERY_ERROR(ReasonCode.CONFLICT),
213        
214        /** Version discordance detected  **/
215        @RpcEnum(id=22)
216        DISCORDANCE_VERSION(ReasonCode.CONFLICT),
217
218        /** Duplicate activity name  **/
219        @RpcEnum(id=23)
220        DUPLICATE_ACTIVITY_NAME(ReasonCode.CONFLICT),
221
222        /** Duplicate stream name  **/
223        @RpcEnum(id=24)
224        DUPLICATE_STREAM_NAME(ReasonCode.CONFLICT),
225
226        /**
227         * This code indicates that an external lock couldn't be acquired
228         * because the lock already exists.
229         */
230        @RpcEnum(id=25)
231        EXTERNAL_LOCK_ALREADY_PRESENT(ReasonCode.CONFLICT),
232
233        /**
234         * Some dependency required by the communication channel failed.
235         */
236        @RpcEnum(id=26)
237        FAILED_DEPENDENCY(ReasonCode.CONFLICT),
238
239        /**
240         * A field did not pass validation during an attempted delivery.
241         */
242        @RpcEnum(id=27)
243        FIELD_VALIDATION(ReasonCode.CONFLICT),
244
245        /**
246         * The client resource resides in a file area whose version is not
247         * compatible with the currently running software.  The file area needs
248         * to be upgraded in order to work with this software.
249         */
250        @RpcEnum(id=28)
251        FILE_AREA_NEEDS_UPGRADE(ReasonCode.CONFLICT),
252
253        /** A file error was encountered */
254        @RpcEnum(id=29)
255        FILE_ERROR(ReasonCode.CONFLICT),
256
257        /**
258         * While firing a named ClearQuest hook, the hook returned a message,
259         * which generally represents an error or need for additional
260         * information
261         */
262        @RpcEnum(id=32)
263        HOOK_RETURNED_MESSAGE(ReasonCode.CONFLICT),
264
265        /**
266         * An in-line query definition during query execution
267         */
268        @RpcEnum(id=35)
269        ILLEGAL_QUERY(ReasonCode.CONFLICT),
270
271        /**
272         * The client resource resides in a file area whose version is not
273         * compatible with the currently running software. The software needs to
274         * be upgraded to handle this file area.
275         */
276        @RpcEnum(id=36)
277        INCOMPATIBLE_FILE_AREA_VERSION(ReasonCode.CONFLICT),
278
279        /** Insufficient permission for the requested operation */
280        @RpcEnum(id=37)
281        INSUFFICIENT_PERMISSION(ReasonCode.INSUFFICIENT_PERMISSION),
282
283        /** An interaction request has occurred */
284        @RpcEnum(id=38)
285        INTERACTION_REQUEST(ReasonCode.CONFLICT),
286
287        /** An internal error has occurred */
288        @RpcEnum(id=39)
289        INTERNAL_ERROR(ReasonCode.CONFLICT),
290
291        /**
292         * The provider's server encountered an unexpected internal error
293         * condition which prevented it from fulfilling the request. This
294         * loosely corresponds to an HTTP 500 Internal Server Error response
295         * from the server.
296         * 
297         * @see #SERVER_ERROR
298         */
299        @RpcEnum(id=40)
300        INTERNAL_SERVER_ERROR(ReasonCode.CONFLICT),
301
302        /**
303         * A required field is missing from or malformed in an StpLocation
304         * specification.
305         */
306        @RpcEnum(id=42)
307        INVALID_OBJECT_SELECTOR(ReasonCode.CONFLICT),
308
309        /** An invalid response was received */
310        @RpcEnum(id=43)
311        INVALID_RESPONSE(ReasonCode.CONFLICT),
312
313        /**
314         * Completion of operation was prevented because one or more properties
315         * have invalid values
316         */
317        @RpcEnum(id=44)
318        INVALID_VALUES(ReasonCode.CONFLICT),
319        
320        /** License error occurred **/
321        @RpcEnum(id=45)
322        LICENSE_ERROR(ReasonCode.CONFLICT),
323
324        /** The database to be affected is currently locked */
325        @RpcEnum(id=46)
326        LOCKED_DATABASE(ReasonCode.CONFLICT),
327
328        /** The name supplied for a new resource is invalid */
329        @RpcEnum(id=48)
330        NAME_MUST_BE_VALID(ReasonCode.CONFLICT),
331
332        /** Resource needs to be merged from latest version  **/
333        @RpcEnum(id=49)
334        NEEDS_MERGE_FROM_LATEST(ReasonCode.CONFLICT),
335
336        /** For use when StpException is just a wrapper for a WvcmException */
337        @RpcEnum(id=50)
338        NONE(ReasonCode.CONFLICT),
339
340        /**
341         * A duplicate record is specified but the action is not a duplicate
342         * action.
343         */
344        @RpcEnum(id=52)
345        NOT_DUPLICATE_ACTION(ReasonCode.CONFLICT),
346
347        /** A parameter mismatch was detected in a response */
348        @RpcEnum(id=57)
349        PARAMETER_MISMATCH(ReasonCode.CONFLICT),
350
351        /** The parent of a targeted resource needs to exist, but doesn't */
352        @RpcEnum(id=58)
353        PARENT_MUST_EXIST(ReasonCode.CONFLICT),
354
355        /**
356         * This exception is reporting failure in an operation that was applied
357         * independently to multiple resources and failed on some of them.
358         * 
359         * @see StpPartialResultsException
360         */
361        @RpcEnum(id=59)
362        PARTIAL_RESULTS(ReasonCode.CONFLICT),
363
364        /** Used when delivering change contexts */
365        @RpcEnum(id=60)
366        PRIOR_COMMIT_FAILURE(ReasonCode.CONFLICT),
367
368        /**
369         * Some other property error such as
370         * <ul>
371         * <li>Can't update value because it is inappropriate for property.
372         * <li>Can't update value because of server-specific restriction such
373         * as length of string or list.
374         * <li>
375         * </ul>
376         */
377        @RpcEnum(id=61)
378        PROPERTY_ERROR(ReasonCode.CONFLICT),
379
380        /**
381         * An exception with this StpReasonCode is thrown by the execution of
382         * any property "getter" method when the targeted property could not be
383         * retrieved from the server. Exceptions of this type wrap the exception
384         * generated by the server, which is accessible via the getCause() or
385         * {@link javax.wvcm.WvcmException#getNestedExceptions()} methods of
386         * this wrapping exception.
387         * <p>
388         * The traceback for the outer, PROPERTY_RETRIEVAL_FAILED exception will
389         * identify the context in which the attempt was made to get the
390         * property value from the proxy, while the traceback for the cause of
391         * that exception will identify the context in which the attempt was
392         * made to read the value into the proxy.
393         */
394        @RpcEnum(id=68)
395        PROPERTY_RETRIEVAL_FAILED(ReasonCode.CONFLICT),
396
397        /**
398         * Thrown by CreateRecord when an attempt is made to create a record with
399         * the same name as one that already exists on the server.
400         */
401        @RpcEnum(id=70)
402        RECORD_WITH_SAME_DISPLAYNAME_EXISTS(ReasonCode.CONFLICT),
403
404        /** Request failed error **/
405        @RpcEnum(id=71)
406        REQUEST_FAILED_ERROR(ReasonCode.CONFLICT),
407
408        /**
409         * The provider has detected something inappropriate with a server's
410         * response. It could be the result of a bug in the server's response or
411         * a bug in the provider's processing of the response.
412         * 
413         * @see #INTERNAL_SERVER_ERROR
414         */
415        @RpcEnum(id=75)
416        SERVER_ERROR(ReasonCode.CONFLICT),
417
418        /** View update cancel failed **/
419        @RpcEnum(id=79)
420        SYNC_CANCEL_FAILED(ReasonCode.CONFLICT),
421
422        /** 
423         * View's config spec is not synchronized with stream's configuration.
424         * An update view operation is required.
425         */
426        @RpcEnum(id=83)
427        VIEW_OUT_OF_SYNC_WITH_STREAM(ReasonCode.CONFLICT),
428
429        /**
430         * The provider was unable to complete the operation for an unspecified
431         * reason.
432         */
433        @RpcEnum(id=31)
434        FORBIDDEN,
435
436        /** Request not understood or contextually incorrect for the provider. */
437        @RpcEnum(id=4)
438        BAD_REQUEST(ReasonCode.FORBIDDEN),
439
440        /** Used by REVERT method */
441        @RpcEnum(id=14)
442        CHILD_ORIGINAL_SOURCE_DIRECTORY_NO_LONGER_EXISTS(ReasonCode.FORBIDDEN),
443
444        /** Used by REVERT method */
445        @RpcEnum(id=13)
446        CHILDREN_OF_FOLDER_MUST_BE_REVERTED_FIRST(ReasonCode.FORBIDDEN),
447
448        /**
449         * Used when an operation is forbidden due to operating in disconnected
450         * mode
451         */
452        @RpcEnum(id=21)
453        DISCONNECTED(ReasonCode.FORBIDDEN),
454
455        /** Used when trying to delete query folders */
456        @RpcEnum(id=30)
457        FOLDER_HAS_CHILDREN(ReasonCode.FORBIDDEN),
458
459        /** An illegal argument was specified */
460        @RpcEnum(id=33)
461        ILLEGAL_ARG(ReasonCode.FORBIDDEN),
462        
463        /** A comment was specified in the load rule section */
464        @RpcEnum(id=93)
465        ILLEGAL_COMMENT_IN_CONFIG_SPEC(ReasonCode.FORBIDDEN),
466
467        /** The request or operation in not valid */
468        @RpcEnum(id=41)
469        INVALID(ReasonCode.FORBIDDEN),
470
471        /**
472         * Thrown by OpenRecord when a duplicate record is not specified with a
473         * duplicate action.
474         */
475        @RpcEnum(id=56)
476        NO_DUPLICATE_RECORD(ReasonCode.FORBIDDEN),
477
478        /** Request not allowed by the provider. */
479        @RpcEnum(id=51)
480        NOT_ALLOWED(ReasonCode.FORBIDDEN),
481
482        /** The request or operation is not supported */
483        @RpcEnum(id=54)
484        NOT_SUPPORTED(ReasonCode.FORBIDDEN),
485
486        /** The submit request is not allowed */
487        @RpcEnum(id=77)
488        SUBMIT_NOT_ALLOWED(ReasonCode.FORBIDDEN),
489
490        /**
491         * Thrown by OpenRecord when the specified action is not defined for the
492         * record type.
493         */
494        @RpcEnum(id=81)
495        UNKNOWN_ACTION(ReasonCode.FORBIDDEN),
496
497        /**
498         * Thrown when a report has been requested on resource that does not
499         * support that report type.
500         */
501        @RpcEnum(id=82)
502        UNSUPPORTED_REPORT(ReasonCode.FORBIDDEN),
503
504        /** Illegal syntax for location string value. */
505        @RpcEnum(id=34)
506        ILLEGAL_LOCATION_SYNTAX,
507
508        /**
509         * <code>Precondition:</code> Report failed since the resource does
510         * not support the specified report.
511         */
512        @RpcEnum(id=3)
513        BAD_REPORT(ReasonCode.METHOD_NOT_SUPPORTED),
514
515        /** The resource has no content. */
516        @RpcEnum(id=55)
517        NO_CONTENT(ReasonCode.METHOD_NOT_SUPPORTED),
518
519        /**
520         * The corresponding remote resource no longer exists or was never
521         * created.
522         */
523        @RpcEnum(id=53)
524        NOT_FOUND,
525        
526        /**
527         * The corresponding resource cannot be found via local lookup.
528         */
529        @RpcEnum(id=92)
530        NOT_FOUND_LOCALLY(ReasonCode.NOT_FOUND),
531        
532        /**
533         * <code>Precondition:</code> Failed to retrieve a property that
534         * should be supported. A potentially recoverable condition prevented
535         * the server from retrieving the property value.
536         */
537        @RpcEnum(id=63)
538        PROPERTY_NOT_CURRENTLY_AVAILABLE,       
539        
540        /**
541         * The requested property value is unavailable because it is not valid
542         * for the targeted resource--the property name used is not defined in
543         * the targeted resource's interface nor is it included in the
544         * PropertyRequest returned by
545         * {@link javax.wvcm.Resource#doGetPropertyNameList(Feedback)} for the
546         * resource.
547         */
548        @RpcEnum(id=64)
549        PROPERTY_NOT_DEFINED_FOR_RESOURCE,
550        
551        /**
552         * The property value is maintained only on the server and so is not
553         * available locally
554         */
555        @RpcEnum(id=62)
556        PROPERTY_NOT_AVAILABLE_LOCALLY(ReasonCode.PROPERTY_NOT_DEFINED_FOR_RESOURCE),
557
558        /**
559         * The property value is unavailable because it was not in the property
560         * name list when the proxy was created nor has it subsequently been
561         * added via {@link Resource#setProperty} or one of the other property
562         * setters.
563         */
564        @RpcEnum(id=65)
565        PROPERTY_NOT_REQUESTED,
566
567        /**
568         * Even though this API says the property is valid for the targeted
569         * resource, neither the server nor client currently support it.
570         */
571        @RpcEnum(id=91)
572        PROPERTY_NOT_SUPPORTED(ReasonCode.CONFLICT),
573        
574        /**
575         * Even though this API says the property is valid for the targeted
576         * resource, the server does not support it. For properties the server
577         * intends to support in the release under development, the exception
578         * message should say NOT YET IMPLEMENTED.
579         */
580        @RpcEnum(id=66)
581        PROPERTY_NOT_SUPPORTED_BY_SERVER,
582
583        /** The property value update would overwrite an earlier change. */
584        @RpcEnum(id=67)
585        PROPERTY_OVERWRITE_FORBIDDEN,
586        
587        /** The provider suffered an I/O failure, the operation may be retried. */
588        @RpcEnum(id=69)
589        READ_FAILED,
590
591        /**
592         * <code>Precondition:</code> Creating a resource failed because a
593         * resource already exists at the specified location.
594         */
595        @RpcEnum(id=73)
596        RESOURCE_ALREADY_EXISTS_AT_LOCATION,
597        
598        /** View update was canceled **/
599        SYNC_CANCELLED (ReasonCode.CONFLICT),
600
601        /** The user is not authorized to execute the attempted operation. */
602        @RpcEnum(id=80)
603        UNAUTHORIZED,
604
605        /** Login on server failed**/
606        @RpcEnum(id=47)
607        LOGIN_FAILED(ReasonCode.UNAUTHORIZED),
608        
609        /** The provider suffered an I/O failure, the operation may be retried. */
610        @RpcEnum(id=84)
611        WRITE_FAILED,
612        
613        /**
614         * Session does not exist or the session has expired.
615         */
616        @RpcEnum(id=76)
617        SESSION_EXPIRED_OR_DOES_NOT_EXIST(ReasonCode.UNAUTHORIZED),
618        
619        /**
620         * Used if an operation requires credentials but none were provided
621         */
622        @RpcEnum(id=19)
623        CREDENTIALS_REQUIRED(ReasonCode.UNAUTHORIZED),
624        
625        /**
626         * Used when the server capacity has been reached.
627         */
628        @RpcEnum(id=74)
629        SERVER_BUSY(ReasonCode.CONFLICT),
630        
631        /**
632         * Used when the client is not compatible with the server.  (This may
633         * be caused by a client that is too old, or too new.)
634         */
635        @RpcEnum(id=85)
636        INCOMPATIBLE_SERVER(ReasonCode.VERSION_NOT_SUPPORTED),
637        
638        @RpcEnum(id=88)
639        RPC_UNEXPECTEDLY_EXITED(ReasonCode.CONFLICT),
640        
641        @RpcEnum(id=89)
642        UNEXPECTED_EXCEPTION(ReasonCode.CONFLICT),
643        
644        ;
645        /* end of enum StpReasonCode */;
646        
647        // ====================================================================
648
649        /**
650         * Returns the WVCM base reason code associated with this STP reason
651         * code.
652         * 
653         * @return The WVCM reason code associated with this STP reason code.
654         */
655        public ReasonCode getWvcmReasonCode()
656        {
657            return m_wvcmReasonCode;
658        }
659
660        /*
661         * A string representation of this reason code.
662         */
663        public String toString()
664        {
665            return name().toLowerCase().replaceAll("_", "-");
666        }
667
668        /**
669         * Constructs an StpReasonCode that is semantically equivalent to the
670         * WVCM ReasonCode of the same name.
671         */
672        private StpReasonCode()
673        {
674            m_wvcmReasonCode = ReasonCode.valueOf(ReasonCode.class, name());
675        }
676
677        /**
678         * Constructs an StpReasonCode as a refinement of a WVCM base
679         * ReasonCode.
680         * 
681         * @param wvcmBaseCode The WVCM reason code that this StpReasonCode
682         *            refines. Cannot be <code>null</code>.
683         */
684        private StpReasonCode(ReasonCode wvcmBaseCode)
685        {
686            m_wvcmReasonCode = wvcmBaseCode;
687        }
688
689        /**
690         * The WVCM reason code classification for this SubReasonCode.
691         */
692        private final ReasonCode m_wvcmReasonCode;
693    }
694
695    /**
696     * Casts an Object to a Type, avoiding a type safety warning. Use sparingly.
697     * May throw ClassCastException at runtime. Some Java compilers can deduce
698     * U from context, such as in an assignment or a return statement; however,
699     * others may not. It is suggested, therefore, that all uses of this method
700     * should include the target type explicitly.
701     * <pre>
702     *  StpException.&lt;desired-type>unchecked_cast(x)
703     * </pre> 
704     * The ugliness of this construct matches the sledge hammer that is being
705     * used to make the code compile without warnings.
706     * 
707     * @param <U> The Type to which the object should be cast
708     * @param obj The Object to be cast
709     * @return The argument Object cast to Type U.
710     */
711    @SuppressWarnings("unchecked")
712    public static <U> U unchecked_cast(Object obj)
713    {
714        return (U)obj;
715    }
716    
717    /**
718     * @return Returns an implementation object that stores the fields of this
719     *         exception not defined by WvcmException and implements the other
720     *         methods of this exception. Will never be <b>null</b>.
721     */
722    public abstract Data data();
723
724    /**
725     * Localizes the message contained within this exception and returns it.
726     */
727    public String getMessage() { return data().getMessage(); }
728    
729    /**
730     * @return The StpReasonCode assigned to this exception.
731     */
732    public StpReasonCode getStpReasonCode()
733    { return data().getStpReasonCode(); }
734    
735    /**
736     * @return A String image of this StpException and any nested Exceptions
737     */
738    public String toString() { return data().toString(); }
739
740    /**
741     * Constructs this exception object for its subclasses.
742     * 
743     * @param resource The Resource argument to WvcmException
744     * @param reasonCode The ReasonCode argument to WvcmException
745     * @param nestedExceptions The Throwable[] argument to WvcmException
746     * 
747     * @see javax.wvcm.WvcmException
748     */
749    protected StpException(Resource resource,
750                           ReasonCode reasonCode,
751                           Throwable... nestedExceptions)
752    {
753        super(null, resource, reasonCode, nestedExceptions);
754    }
755}