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