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
014package com.ibm.rational.wvcm.stp;
015
016import javax.wvcm.Feedback;
017import javax.wvcm.Resource;
018import javax.wvcm.WvcmException;
019
020import com.ibm.rational.wvcm.stpex.StpExEnumeration;
021import 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 */
053public 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        /** A comment was specified in the load rule section */
466        @RpcEnum(id=93)
467        ILLEGAL_COMMENT_IN_CONFIG_SPEC(ReasonCode.FORBIDDEN),
468
469        /** The request or operation in not valid */
470        @RpcEnum(id=41)
471        INVALID(ReasonCode.FORBIDDEN),
472
473        /**
474         * Thrown by OpenRecord when a duplicate record is not specified with a
475         * duplicate action.
476         */
477        @RpcEnum(id=56)
478        NO_DUPLICATE_RECORD(ReasonCode.FORBIDDEN),
479
480        /** Request not allowed by the provider. */
481        @RpcEnum(id=51)
482        NOT_ALLOWED(ReasonCode.FORBIDDEN),
483
484        /** The request or operation is not supported */
485        @RpcEnum(id=54)
486        NOT_SUPPORTED(ReasonCode.FORBIDDEN),
487
488        /** The submit request is not allowed */
489        @RpcEnum(id=77)
490        SUBMIT_NOT_ALLOWED(ReasonCode.FORBIDDEN),
491
492        /**
493         * Thrown by OpenRecord when the specified action is not defined for the
494         * record type.
495         */
496        @RpcEnum(id=81)
497        UNKNOWN_ACTION(ReasonCode.FORBIDDEN),
498
499        /**
500         * Thrown when a report has been requested on resource that does not
501         * support that report type.
502         */
503        @RpcEnum(id=82)
504        UNSUPPORTED_REPORT(ReasonCode.FORBIDDEN),
505
506        /** Illegal syntax for location string value. */
507        @RpcEnum(id=34)
508        ILLEGAL_LOCATION_SYNTAX,
509
510        /**
511         * <code>Precondition:</code> Report failed since the resource does
512         * not support the specified report.
513         */
514        @RpcEnum(id=3)
515        BAD_REPORT(ReasonCode.METHOD_NOT_SUPPORTED),
516
517        /** The resource has no content. */
518        @RpcEnum(id=55)
519        NO_CONTENT(ReasonCode.METHOD_NOT_SUPPORTED),
520
521        /**
522         * The corresponding remote resource no longer exists or was never
523         * created.
524         */
525        @RpcEnum(id=53)
526        NOT_FOUND,
527        
528        /**
529         * The corresponding resource cannot be found via local lookup.
530         */
531        @RpcEnum(id=92)
532        NOT_FOUND_LOCALLY(ReasonCode.NOT_FOUND),
533        
534        /**
535         * <code>Precondition:</code> Failed to retrieve a property that
536         * should be supported. A potentially recoverable condition prevented
537         * the server from retrieving the property value.
538         */
539        @RpcEnum(id=63)
540        PROPERTY_NOT_CURRENTLY_AVAILABLE,       
541        
542        /**
543         * The requested property value is unavailable because it is not valid
544         * for the targeted resource--the property name used is not defined in
545         * the targeted resource's interface nor is it included in the
546         * PropertyRequest returned by
547         * {@link javax.wvcm.Resource#doGetPropertyNameList(Feedback)} for the
548         * resource.
549         */
550        @RpcEnum(id=64)
551        PROPERTY_NOT_DEFINED_FOR_RESOURCE,
552        
553        /**
554         * The property value is maintained only on the server and so is not
555         * available locally
556         */
557        @RpcEnum(id=62)
558        PROPERTY_NOT_AVAILABLE_LOCALLY(ReasonCode.PROPERTY_NOT_DEFINED_FOR_RESOURCE),
559
560        /**
561         * The property value is unavailable because it was not in the property
562         * name list when the proxy was created nor has it subsequently been
563         * added via {@link Resource#setProperty} or one of the other property
564         * setters.
565         */
566        @RpcEnum(id=65)
567        PROPERTY_NOT_REQUESTED,
568
569        /**
570         * Even though this API says the property is valid for the targeted
571         * resource, neither the server nor client currently support it.
572         */
573        @RpcEnum(id=91)
574        PROPERTY_NOT_SUPPORTED(ReasonCode.CONFLICT),
575        
576        /**
577         * Even though this API says the property is valid for the targeted
578         * resource, the server does not support it. For properties the server
579         * intends to support in the release under development, the exception
580         * message should say NOT YET IMPLEMENTED.
581         */
582        @RpcEnum(id=66)
583        PROPERTY_NOT_SUPPORTED_BY_SERVER,
584
585        /** The property value update would overwrite an earlier change. */
586        @RpcEnum(id=67)
587        PROPERTY_OVERWRITE_FORBIDDEN,
588        
589        /** The provider suffered an I/O failure, the operation may be retried. */
590        @RpcEnum(id=69)
591        READ_FAILED,
592
593        /**
594         * <code>Precondition:</code> Creating a resource failed because a
595         * resource already exists at the specified location.
596         */
597        @RpcEnum(id=73)
598        RESOURCE_ALREADY_EXISTS_AT_LOCATION,
599        
600        /** View update was canceled **/
601        SYNC_CANCELLED (ReasonCode.CONFLICT),
602
603        /** The user is not authorized to execute the attempted operation. */
604        @RpcEnum(id=80)
605        UNAUTHORIZED,
606
607        /** Login on server failed**/
608        @RpcEnum(id=47)
609        LOGIN_FAILED(ReasonCode.UNAUTHORIZED),
610        
611        /** The provider suffered an I/O failure, the operation may be retried. */
612        @RpcEnum(id=84)
613        WRITE_FAILED,
614        
615        /**
616         * Session does not exist or the session has expired.
617         */
618        @RpcEnum(id=76)
619        SESSION_EXPIRED_OR_DOES_NOT_EXIST(ReasonCode.UNAUTHORIZED),
620        
621        /**
622         * Used if an operation requires credentials but none were provided
623         */
624        @RpcEnum(id=19)
625        CREDENTIALS_REQUIRED(ReasonCode.UNAUTHORIZED),
626        
627        /**
628         * Used when the server capacity has been reached.
629         */
630        @RpcEnum(id=74)
631        SERVER_BUSY(ReasonCode.CONFLICT),
632        
633        /**
634         * Used when the client is not compatible with the server.  (This may
635         * be caused by a client that is too old, or too new.)
636         */
637        @RpcEnum(id=85)
638        INCOMPATIBLE_SERVER(ReasonCode.VERSION_NOT_SUPPORTED),
639        
640        @RpcEnum(id=88)
641        RPC_UNEXPECTEDLY_EXITED(ReasonCode.CONFLICT),
642        
643        @RpcEnum(id=89)
644        UNEXPECTED_EXCEPTION(ReasonCode.CONFLICT),
645        
646        ;
647        /* end of enum StpReasonCode */;
648        
649        // ====================================================================
650
651        /**
652         * Returns the WVCM base reason code associated with this STP reason
653         * code.
654         * 
655         * @return The WVCM reason code associated with this STP reason code.
656         */
657        public ReasonCode getWvcmReasonCode()
658        {
659            return m_wvcmReasonCode;
660        }
661
662        /*
663         * A string representation of this reason code.
664         */
665        public String toString()
666        {
667            return name().toLowerCase().replaceAll("_", "-");
668        }
669
670        /**
671         * Constructs an StpReasonCode that is semantically equivalent to the
672         * WVCM ReasonCode of the same name.
673         */
674        private StpReasonCode()
675        {
676            m_wvcmReasonCode = ReasonCode.valueOf(ReasonCode.class, name());
677        }
678
679        /**
680         * Constructs an StpReasonCode as a refinement of a WVCM base
681         * ReasonCode.
682         * 
683         * @param wvcmBaseCode The WVCM reason code that this StpReasonCode
684         *            refines. Cannot be <code>null</code>.
685         */
686        private StpReasonCode(ReasonCode wvcmBaseCode)
687        {
688            m_wvcmReasonCode = wvcmBaseCode;
689        }
690
691        /**
692         * The WVCM reason code classification for this SubReasonCode.
693         */
694        private final ReasonCode m_wvcmReasonCode;
695    }
696
697    /**
698     * Casts an Object to a Type, avoiding a type safety warning. Use sparingly.
699     * May throw ClassCastException at runtime. Some Java compilers can deduce
700     * U from context, such as in an assignment or a return statement; however,
701     * others may not. It is suggested, therefore, that all uses of this method
702     * should include the target type explicitly.
703     * <pre>
704     *  StpException.&lt;desired-type>unchecked_cast(x)
705     * </pre> 
706     * The ugliness of this construct matches the sledge hammer that is being
707     * used to make the code compile without warnings.
708     * 
709     * @param <U> The Type to which the object should be cast
710     * @param obj The Object to be cast
711     * @return The argument Object cast to Type U.
712     */
713    @SuppressWarnings("unchecked")
714    public static <U> U unchecked_cast(Object obj)
715    {
716        return (U)obj;
717    }
718    
719    /**
720     * @return Returns an implementation object that stores the fields of this
721     *         exception not defined by WvcmException and implements the other
722     *         methods of this exception. Will never be <b>null</b>.
723     */
724    public abstract Data data();
725
726    /**
727     * Localizes the message contained within this exception and returns it.
728     */
729    public String getMessage() { return data().getMessage(); }
730    
731    /**
732     * @return The StpReasonCode assigned to this exception.
733     */
734    public StpReasonCode getStpReasonCode()
735    { return data().getStpReasonCode(); }
736    
737    /**
738     * @return A String image of this StpException and any nested Exceptions
739     */
740    public String toString() { return data().toString(); }
741
742    /**
743     * Constructs this exception object for its subclasses.
744     * 
745     * @param resource The Resource argument to WvcmException
746     * @param reasonCode The ReasonCode argument to WvcmException
747     * @param nestedExceptions The Throwable[] argument to WvcmException
748     * 
749     * @see javax.wvcm.WvcmException
750     */
751    protected StpException(Resource resource,
752                           ReasonCode reasonCode,
753                           Throwable... nestedExceptions)
754    {
755        super(null, resource, reasonCode, nestedExceptions);
756    }
757}