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, 2010.  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             * An attempt to deliver a resource from the change context to the
204             * database failed.
205             */
206            @RpcEnum(id=20)
207            DELIVERY_ERROR(ReasonCode.CONFLICT),
208            
209            /** Version discordance detected  **/
210            @RpcEnum(id=22)
211            DISCORDANCE_VERSION(ReasonCode.CONFLICT),
212    
213            /** Duplicate activity name  **/
214            @RpcEnum(id=23)
215            DUPLICATE_ACTIVITY_NAME(ReasonCode.CONFLICT),
216    
217            /** Duplicate stream name  **/
218            @RpcEnum(id=24)
219            DUPLICATE_STREAM_NAME(ReasonCode.CONFLICT),
220    
221            /**
222             * This code indicates that an external lock couldn't be acquired
223             * because the lock already exists.
224             */
225            @RpcEnum(id=25)
226            EXTERNAL_LOCK_ALREADY_PRESENT(ReasonCode.CONFLICT),
227    
228            /**
229             * Some dependency required by the communication channel failed.
230             */
231            @RpcEnum(id=26)
232            FAILED_DEPENDENCY(ReasonCode.CONFLICT),
233    
234            /**
235             * A field did not pass validation during an attempted delivery.
236             */
237            @RpcEnum(id=27)
238            FIELD_VALIDATION(ReasonCode.CONFLICT),
239    
240            /**
241             * The client resource resides in a file area whose version is not
242             * compatible with the currently running software.  The file area needs
243             * to be upgraded in order to work with this software.
244             */
245            @RpcEnum(id=28)
246            FILE_AREA_NEEDS_UPGRADE(ReasonCode.CONFLICT),
247    
248            /** A file error was encountered */
249            @RpcEnum(id=29)
250            FILE_ERROR(ReasonCode.CONFLICT),
251    
252            /**
253             * While firing a named ClearQuest hook, the hook returned a message,
254             * which generally represents an error or need for additional
255             * information
256             */
257            @RpcEnum(id=32)
258            HOOK_RETURNED_MESSAGE(ReasonCode.CONFLICT),
259    
260            /**
261             * An in-line query definition during query execution
262             */
263            @RpcEnum(id=35)
264            ILLEGAL_QUERY(ReasonCode.CONFLICT),
265    
266            /**
267             * The client resource resides in a file area whose version is not
268             * compatible with the currently running software. The software needs to
269             * be upgraded to handle this file area.
270             */
271            @RpcEnum(id=36)
272            INCOMPATIBLE_FILE_AREA_VERSION(ReasonCode.CONFLICT),
273    
274            /** Insufficient permission for the requested operation */
275            @RpcEnum(id=37)
276            INSUFFICIENT_PERMISSION(ReasonCode.CONFLICT),
277    
278            /** An interaction request has occurred */
279            @RpcEnum(id=38)
280            INTERACTION_REQUEST(ReasonCode.CONFLICT),
281    
282            /** An internal error has occurred */
283            @RpcEnum(id=39)
284            INTERNAL_ERROR(ReasonCode.CONFLICT),
285    
286            /**
287             * The provider's server encountered an unexpected internal error
288             * condition which prevented it from fulfilling the request. This
289             * loosely corresponds to an HTTP 500 Internal Server Error response
290             * from the server.
291             * 
292             * @see #SERVER_ERROR
293             */
294            @RpcEnum(id=40)
295            INTERNAL_SERVER_ERROR(ReasonCode.CONFLICT),
296    
297            /**
298             * A required field is missing from or malformed in an StpLocation
299             * specification.
300             */
301            @RpcEnum(id=42)
302            INVALID_OBJECT_SELECTOR(ReasonCode.CONFLICT),
303    
304            /** An invalid response was received */
305            @RpcEnum(id=43)
306            INVALID_RESPONSE(ReasonCode.CONFLICT),
307    
308            /**
309             * Completion of operation was prevented because one or more properties
310             * have invalid values
311             */
312            @RpcEnum(id=44)
313            INVALID_VALUES(ReasonCode.CONFLICT),
314            
315            /** License error occurred **/
316            @RpcEnum(id=45)
317            LICENSE_ERROR(ReasonCode.CONFLICT),
318    
319            /** The database to be affected is currently locked */
320            @RpcEnum(id=46)
321            LOCKED_DATABASE(ReasonCode.CONFLICT),
322    
323            /** The name supplied for a new resource is invalid */
324            @RpcEnum(id=48)
325            NAME_MUST_BE_VALID(ReasonCode.CONFLICT),
326    
327            /** Resource needs to be merged from latest version  **/
328            @RpcEnum(id=49)
329            NEEDS_MERGE_FROM_LATEST(ReasonCode.CONFLICT),
330    
331            /** For use when StpException is just a wrapper for a WvcmException */
332            @RpcEnum(id=50)
333            NONE(ReasonCode.CONFLICT),
334    
335            /**
336             * A duplicate record is specified but the action is not a duplicate
337             * action.
338             */
339            @RpcEnum(id=52)
340            NOT_DUPLICATE_ACTION(ReasonCode.CONFLICT),
341    
342            /** A parameter mismatch was detected in a response */
343            @RpcEnum(id=57)
344            PARAMETER_MISMATCH(ReasonCode.CONFLICT),
345    
346            /** The parent of a targeted resource needs to exist, but doesn't */
347            @RpcEnum(id=58)
348            PARENT_MUST_EXIST(ReasonCode.CONFLICT),
349    
350            /**
351             * This exception is reporting failure in an operation that was applied
352             * independently to multiple resources and failed on some of them.
353             * 
354             * @see StpPartialResultsException
355             */
356            @RpcEnum(id=59)
357            PARTIAL_RESULTS(ReasonCode.CONFLICT),
358    
359            /** Used when delivering change contexts */
360            @RpcEnum(id=60)
361            PRIOR_COMMIT_FAILURE(ReasonCode.CONFLICT),
362    
363            /**
364             * Some other property error such as
365             * <ul>
366             * <li>Can't update value because it is inappropriate for property.
367             * <li>Can't update value because of server-specific restriction such
368             * as length of string or list.
369             * <li>
370             * </ul>
371             */
372            @RpcEnum(id=61)
373            PROPERTY_ERROR(ReasonCode.CONFLICT),
374    
375            /**
376             * An exception with this StpReasonCode is thrown by the execution of
377             * any property "getter" method when the targeted property could not be
378             * retrieved from the server. Exceptions of this type wrap the exception
379             * generated by the server, which is accessible via the getCause() or
380             * {@link javax.wvcm.WvcmException#getNestedExceptions()} methods of
381             * this wrapping exception.
382             * <p>
383             * The traceback for the outer, PROPERTY_RETRIEVAL_FAILED exception will
384             * identify the context in which the attempt was made to get the
385             * property value from the proxy, while the traceback for the cause of
386             * that exception will identify the context in which the attempt was
387             * made to read the value into the proxy.
388             */
389            @RpcEnum(id=68)
390            PROPERTY_RETRIEVAL_FAILED(ReasonCode.CONFLICT),
391    
392            /**
393             * Thrown by CreateRecord when an attempt is made to create a record with
394             * the same name as one that already exists on the server.
395             */
396            @RpcEnum(id=70)
397            RECORD_WITH_SAME_DISPLAYNAME_EXISTS(ReasonCode.CONFLICT),
398    
399            /** Request failed error **/
400            @RpcEnum(id=71)
401            REQUEST_FAILED_ERROR(ReasonCode.CONFLICT),
402    
403            /**
404             * The provider has detected something inappropriate with a server's
405             * response. It could be the result of a bug in the server's response or
406             * a bug in the provider's processing of the response.
407             * 
408             * @see #INTERNAL_SERVER_ERROR
409             */
410            @RpcEnum(id=75)
411            SERVER_ERROR(ReasonCode.CONFLICT),
412    
413            /** View update cancel failed **/
414            @RpcEnum(id=79)
415            SYNC_CANCEL_FAILED(ReasonCode.CONFLICT),
416    
417            /** 
418             * View's config spec is not synchronized with stream's configuration.
419             * An update view operation is required.
420             */
421            @RpcEnum(id=83)
422            VIEW_OUT_OF_SYNC_WITH_STREAM(ReasonCode.CONFLICT),
423    
424            /**
425             * The provider was unable to complete the operation for an unspecified
426             * reason.
427             */
428            @RpcEnum(id=31)
429            FORBIDDEN,
430    
431            /** Request not understood or contextually incorrect for the provider. */
432            @RpcEnum(id=4)
433            BAD_REQUEST(ReasonCode.FORBIDDEN),
434    
435            /** Used by REVERT method */
436            @RpcEnum(id=14)
437            CHILD_ORIGINAL_SOURCE_DIRECTORY_NO_LONGER_EXISTS(ReasonCode.FORBIDDEN),
438    
439            /** Used by REVERT method */
440            @RpcEnum(id=13)
441            CHILDREN_OF_FOLDER_MUST_BE_REVERTED_FIRST(ReasonCode.FORBIDDEN),
442    
443            /**
444             * Used when an operation is forbidden due to operating in disconnected
445             * mode
446             */
447            @RpcEnum(id=21)
448            DISCONNECTED(ReasonCode.FORBIDDEN),
449    
450            /** Used when trying to delete query folders */
451            @RpcEnum(id=30)
452            FOLDER_HAS_CHILDREN(ReasonCode.FORBIDDEN),
453    
454            /** An illegal argument was specified */
455            @RpcEnum(id=33)
456            ILLEGAL_ARG(ReasonCode.FORBIDDEN),
457    
458            /** The request or operation in not valid */
459            @RpcEnum(id=41)
460            INVALID(ReasonCode.FORBIDDEN),
461    
462            /**
463             * Thrown by OpenRecord when a duplicate record is not specified with a
464             * duplicate action.
465             */
466            @RpcEnum(id=56)
467            NO_DUPLICATE_RECORD(ReasonCode.FORBIDDEN),
468    
469            /** Request not allowed by the provider. */
470            @RpcEnum(id=51)
471            NOT_ALLOWED(ReasonCode.FORBIDDEN),
472    
473            /** The request or operation is not supported */
474            @RpcEnum(id=54)
475            NOT_SUPPORTED(ReasonCode.FORBIDDEN),
476    
477            /** The submit request is not allowed */
478            @RpcEnum(id=77)
479            SUBMIT_NOT_ALLOWED(ReasonCode.FORBIDDEN),
480    
481            /**
482             * Thrown by OpenRecord when the specified action is not defined for the
483             * record type.
484             */
485            @RpcEnum(id=81)
486            UNKNOWN_ACTION(ReasonCode.FORBIDDEN),
487    
488            /**
489             * Thrown when a report has been requested on resource that does not
490             * support that report type.
491             */
492            @RpcEnum(id=82)
493            UNSUPPORTED_REPORT(ReasonCode.FORBIDDEN),
494    
495            /** Illegal syntax for location string value. */
496            @RpcEnum(id=34)
497            ILLEGAL_LOCATION_SYNTAX,
498    
499            /**
500             * <code>Precondition:</code> Report failed since the resource does
501             * not support the specified report.
502             */
503            @RpcEnum(id=3)
504            BAD_REPORT(ReasonCode.METHOD_NOT_SUPPORTED),
505    
506            /** The resource has no content. */
507            @RpcEnum(id=55)
508            NO_CONTENT(ReasonCode.METHOD_NOT_SUPPORTED),
509    
510            /**
511             * The corresponding remote resource no longer exists or was never
512             * created.
513             */
514            @RpcEnum(id=53)
515            NOT_FOUND,
516            
517            /**
518             * <code>Precondition:</code> Failed to retrieve a property that
519             * should be supported. A potentially recoverable condition prevented
520             * the server from retrieving the property value.
521             */
522            @RpcEnum(id=63)
523            PROPERTY_NOT_CURRENTLY_AVAILABLE,       
524            
525            /**
526             * The requested property value is unavailable because it is not valid
527             * for the targeted resource--the property name used is not defined in
528             * the targeted resource's interface nor is it included in the
529             * PropertyRequest returned by
530             * {@link javax.wvcm.Resource#doGetPropertyNameList(Feedback)} for the
531             * resource.
532             */
533            @RpcEnum(id=64)
534            PROPERTY_NOT_DEFINED_FOR_RESOURCE,
535            
536            /**
537             * The property value is maintained only on the server and so is not
538             * available locally
539             */
540            @RpcEnum(id=62)
541            PROPERTY_NOT_AVAILABLE_LOCALLY(ReasonCode.PROPERTY_NOT_DEFINED_FOR_RESOURCE),
542    
543            /**
544             * The property value is unavailable because it was not in the property
545             * name list when the proxy was created nor has it subsequently been
546             * added via {@link Resource#setProperty} or one of the other property
547             * setters.
548             */
549            @RpcEnum(id=65)
550            PROPERTY_NOT_REQUESTED,
551    
552            /**
553             * Even though this API says the property is valid for the targeted
554             * resource, the server does not support it. For properties the server
555             * intends to support in the release under development, the exception
556             * message should say “NOT YET IMPLEMENTED”.
557             */
558            @RpcEnum(id=66)
559            PROPERTY_NOT_SUPPORTED_BY_SERVER,
560    
561            /** The property value update would overwrite an earlier change. */
562            @RpcEnum(id=67)
563            PROPERTY_OVERWRITE_FORBIDDEN,
564            
565            /** The provider suffered an I/O failure, the operation may be retried. */
566            @RpcEnum(id=69)
567            READ_FAILED,
568    
569            /**
570             * <code>Precondition:</code> Creating a resource failed because a
571             * resource already exists at the specified location.
572             */
573            @RpcEnum(id=73)
574            RESOURCE_ALREADY_EXISTS_AT_LOCATION,
575            
576            /** View update was canceled **/
577            SYNC_CANCELLED (ReasonCode.CONFLICT),
578    
579            /** The user is not authorized to execute the attempted operation. */
580            @RpcEnum(id=80)
581            UNAUTHORIZED,
582    
583            /** Login on server failed**/
584            @RpcEnum(id=47)
585            LOGIN_FAILED(ReasonCode.UNAUTHORIZED),
586            
587            /** The provider suffered an I/O failure, the operation may be retried. */
588            @RpcEnum(id=84)
589            WRITE_FAILED,
590            
591            /**
592             * Session does not exist or the session has expired.
593             */
594            @RpcEnum(id=76)
595            SESSION_EXPIRED_OR_DOES_NOT_EXIST(ReasonCode.UNAUTHORIZED),
596            
597            /**
598             * Used if an operation requires credentials but none were provided
599             */
600            @RpcEnum(id=19)
601            CREDENTIALS_REQUIRED(ReasonCode.UNAUTHORIZED),
602            
603            /**
604             * Used when the server capacity has been reached.
605             */
606            @RpcEnum(id=74)
607            SERVER_BUSY(ReasonCode.CONFLICT),
608            
609            /**
610             * Used when the client is not compatible with the server.  (This may
611             * be caused by a client that is too old, or too new.)
612             */
613            @RpcEnum(id=85)
614            INCOMPATIBLE_SERVER(ReasonCode.VERSION_NOT_SUPPORTED),
615            
616            @RpcEnum(id=88)
617            RPC_UNEXPECTEDLY_EXITED(ReasonCode.CONFLICT),
618            
619            @RpcEnum(id=89)
620            UNEXPECTED_EXCEPTION(ReasonCode.CONFLICT),
621            
622            ;
623            /* end of enum StpReasonCode */;
624            
625            // ====================================================================
626    
627            /**
628             * Returns the WVCM base reason code associated with this STP reason
629             * code.
630             * 
631             * @return The WVCM reason code associated with this STP reason code.
632             */
633            public ReasonCode getWvcmReasonCode()
634            {
635                return m_wvcmReasonCode;
636            }
637    
638            /*
639             * A string representation of this reason code.
640             */
641            public String toString()
642            {
643                return name().toLowerCase().replaceAll("_", "-");
644            }
645    
646            /**
647             * Constructs an StpReasonCode that is semantically equivalent to the
648             * WVCM ReasonCode of the same name.
649             */
650            private StpReasonCode()
651            {
652                m_wvcmReasonCode = ReasonCode.valueOf(ReasonCode.class, name());
653            }
654    
655            /**
656             * Constructs an StpReasonCode as a refinement of a WVCM base
657             * ReasonCode.
658             * 
659             * @param wvcmBaseCode The WVCM reason code that this StpReasonCode
660             *            refines. Cannot be <code>null</code>.
661             */
662            private StpReasonCode(ReasonCode wvcmBaseCode)
663            {
664                m_wvcmReasonCode = wvcmBaseCode;
665            }
666    
667            /**
668             * The WVCM reason code classification for this SubReasonCode.
669             */
670            private final ReasonCode m_wvcmReasonCode;
671        }
672    
673        /**
674         * Casts an Object to a Type, avoiding a type safety warning. Use sparingly.
675         * May throw ClassCastException at runtime. Some Java compilers can deduce
676         * U from context, such as in an assignment or a return statement; however,
677         * others may not. It is suggested, therefore, that all uses of this method
678         * should include the target type explicitly.
679         * <pre>
680         *  StpException.&lt;desired-type>unchecked_cast(x)
681         * </pre> 
682         * The ugliness of this construct matches the sledge hammer that is being
683         * used to make the code compile without warnings.
684         * 
685         * @param <U> The Type to which the object should be cast
686         * @param obj The Object to be cast
687         * @return The argument Object cast to Type U.
688         */
689        @SuppressWarnings("unchecked")
690        public static <U> U unchecked_cast(Object obj)
691        {
692            return (U)obj;
693        }
694        
695        /**
696         * @return Returns an implementation object that stores the fields of this
697         *         exception not defined by WvcmException and implements the other
698         *         methods of this exception. Will never be <b>null</b>.
699         */
700        public abstract Data data();
701    
702        /**
703         * Localizes the message contained within this exception and returns it.
704         */
705        public String getMessage() { return data().getMessage(); }
706        
707        /**
708         * @return The StpReasonCode assigned to this exception.
709         */
710        public StpReasonCode getStpReasonCode()
711        { return data().getStpReasonCode(); }
712        
713        /**
714         * @return A String image of this StpException and any nested Exceptions
715         */
716        public String toString() { return data().toString(); }
717    
718        /**
719         * Constructs this exception object for its subclasses.
720         * 
721         * @param resource The Resource argument to WvcmException
722         * @param reasonCode The ReasonCode argument to WvcmException
723         * @param nestedExceptions The Throwable[] argument to WvcmException
724         * 
725         * @see javax.wvcm.WvcmException
726         */
727        protected StpException(Resource resource,
728                               ReasonCode reasonCode,
729                               Throwable... nestedExceptions)
730        {
731            super(null, resource, reasonCode, nestedExceptions);
732        }
733    }