// // Copyright (c)1998-2011 Pearson Education, Inc. or its affiliate(s). // All rights reserved. // package openadk.library; import openadk.library.infra.*; /** * SIFException describes a SIF error condition. * * When handling inbound messages, the agent may throw a SIFException from a * message handler to signal that an error has occurred and should be returned * to the ZIS in the SIF_Ack message. The ADK will convert the SIFException to * a SIF_Error element when sending the associated SIF_Ack. It is desirable to * throw SIFException in your message handlers (versus generic exceptions) if * you want control over setting the SIF_Error category, code, description, and * extended description elements.<p> * * SIFException may also be thrown by ADK methods in response to a SIF_Ack * received from the server. The actual SIF_Ack object that generated the exception * can be retrieved by calling <code>getAck</code>. Any SIF_Error elements * included in the acknowledgement can be retrieved by calling <code>getErrors</code> * and associated methods such as <code>hasError</code>. Note SIF 1.0r1 allowed * for multiple SIF_Error elements per SIF_Ack, but later versions of SIF do * not. For backward compatibility, the ADK captures all SIF_Error elements * received in SIF_Ack messages and makes them available as an array. The array * can be obtained by calling the <code>getErrors</code> method.<p> * * @author Eric Petersen * @version ADK 1.0 */ public class SIFException extends ADKMessagingException { /** * */ private static final long serialVersionUID = Element.CURRENT_SERIALIZE_VERSION; /** * The SIF_Ack that caused this exception (if the exception was raised in * response to an incoming message) */ public SIF_Ack fAck; /** * Optional SIF_Errors wrapped by this exception */ protected SIF_Error fError; /** * Constructs an exception to wrap one or more SIF_Errors received from an * inbound SIF_Ack message. This form of constructor is only called by * the ADK. */ /** * @param ack The SIF_Ack to use * @param zone The zone that this error applies to */ public SIFException( SIF_Ack ack, Zone zone ) { super(null,zone); fAck = ack; fError = ack != null ? ack.getSIF_Error() : null; } /** * Constructs an exception to wrap one or more SIF_Errors received from an * inbound SIF_Ack message. This form of constructor is only called by * the ADK. */ /** * @param msg The error message * @param ack a SIF_Ack element to use * @param zone The zone that this error applies to */ public SIFException( String msg, SIF_Ack ack, Zone zone ) { super(msg,zone); fAck = ack; fError = ack != null ? ack.getSIF_Error() : null; } /** * Constructs a SIFException for delivery to the ZIS. The ADK will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the ADK, but may also be called by agent code if an * exception occurs in a <i>Publisher</i>, <i>Subscriber</i>, or <i>QueryResults</i> * message handler implementation. * * @deprecated Please use the overload that uses SIFErrorCategory as the first parameter * * @param category A <code>SIFErrorCodes.CAT_</code> error category * @param code A <code>SIFErrorCodes</code> error code * @param desc The error description * @param zone The zone on which the error occurred */ public SIFException( int category, int code, String desc, Zone zone ) { this( category, code, desc, null, zone ); } /** * Constructs a SIFException for delivery to the ZIS. The ADK will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the ADK, but may also be called by agent code if an * exception occurs in a <i>Publisher</i>, <i>Subscriber</i>, or <i>QueryResults</i> * message handler implementation. * * @deprecated Please use the overload that uses SIFErrorCategory as the first parameter * @param category A <code>SIFErrorCodes.CAT_</code> error category * @param code A <code>SIFErrorCodes</code> error code * @param desc The error description * @param extDesc An option extended error description * @param zone The zone on which the error occurred */ public SIFException( int category, int code, String desc, String extDesc, Zone zone ) { super( desc, zone ); fAck = null; SIF_Error error = new SIF_Error( category, code, desc == null ? "" : desc ); if( extDesc != null ){ error.setSIF_ExtendedDesc( extDesc ); } fError = error; } /** * Constructs a SifException for delivery to the ZIS<p> * * The Adk will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the Adk, but may also be called by agent code if an * exception occurs in a <c>IPublisher</c>, <c>ISubscriber</c>, or <c>IQueryResults</c> * message handler implementation. * @deprecated Please use the overload that uses SIFErrorCategory as the first parameter * * @param category A <c>SifErrorCategoryCode.</c> error category * @param code A <c>SifErrorCodes</c> error code * @param desc The error description * @param extDesc An optional extended error description * @param zone The zone on which the error occurred * @param innerException The internal error that was thrown by the agent */ public SIFException( int category, int code, String desc, String extDesc, Zone zone, Exception innerException ) { super( desc, zone, innerException ); fAck = null; SIF_Error error = new SIF_Error( category, code, desc == null ? "" : desc ); if( extDesc != null ){ error.setSIF_ExtendedDesc( extDesc ); } fError = error; } /** * Constructs a SifException for delivery to the ZIS<p> * * The Adk will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the Adk, but may also be called by agent code if an * exception occurs in a <c>IPublisher</c>, <c>ISubscriber</c>, or <c>IQueryResults</c> * message handler implementation. * @deprecated Please use the overload that uses SIFErrorCategory as the first parameter * @param category A <c>SifErrorCategoryCode.</c> error category * @param code A <c>SifErrorCodes</c> error code * @param desc The error description * @param zone The zone on which the error occurred * @param innerException The internal error that was thrown by the agent */ public SIFException( int category, int code, String desc, Zone zone, Exception innerException ) { this( category, code, desc, null, zone, innerException ); } /** * Constructs a SIFException for delivery to the ZIS. The ADK will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the ADK, but may also be called by agent code if an * exception occurs in a <i>Publisher</i>, <i>Subscriber</i>, or <i>QueryResults</i> * message handler implementation. * * @param category The category that applies to this type of error * @param code A <code>SIFErrorCodes</code> error code * @param desc The error description * @param zone The zone on which the error occurred */ public SIFException( SIFErrorCategory category, int code, String desc, Zone zone ) { this( category, code, desc, null, zone ); } /** * Constructs a SIFException for delivery to the ZIS. The ADK will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the ADK, but may also be called by agent code if an * exception occurs in a <i>Publisher</i>, <i>Subscriber</i>, or <i>QueryResults</i> * message handler implementation. * * @param category The category that applies to this type of error * @param code A <code>SIFErrorCodes</code> error code * @param desc The error description * @param extDesc An option extended error description * @param zone The zone on which the error occurred */ public SIFException( SIFErrorCategory category, int code, String desc, String extDesc, Zone zone ) { super( desc, zone ); fAck = null; SIF_Error error = new SIF_Error( category, code, desc == null ? "" : desc, extDesc ); fError = error; } /** * Constructs a SifException for delivery to the ZIS<p> * * The Adk will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the Adk, but may also be called by agent code if an * exception occurs in a <c>Publisher</c>, <c>Subscriber</c>, or <c>QueryResults</c> * message handler implementation. * * @param category The category that applies to this type of error * @param code A <c>SifErrorCodes</c> error code * @param desc The error description * @param zone The zone on which the error occurred * @param innerException The internal error that was thrown by the agent */ public SIFException( SIFErrorCategory category, int code, String desc, Zone zone, Exception innerException ) { this( category, code, desc, null, zone, innerException ); } /** * Constructs a SifException for delivery to the ZIS<p> * * The Adk will include * the error information provided by the exception when it sends a SIF_Ack * in response to the message being processed. This form of constructor is * typically called by the Adk, but may also be called by agent code if an * exception occurs in a <c>IPublisher</c>, <c>ISubscriber</c>, or <c>IQueryResults</c> * message handler implementation. * * @param category The category that applies to this type of error * @param code A <c>SifErrorCodes</c> error code * @param desc The error description * @param extDesc An optional extended error description * @param zone The zone on which the error occurred * @param innerException The internal error that was thrown by the agent */ public SIFException( SIFErrorCategory category, int code, String desc, String extDesc, Zone zone, Exception innerException ) { super( desc, zone, innerException ); fAck = null; if( extDesc == null && innerException != null ){ extDesc = innerException.getMessage(); } SIF_Error error = new SIF_Error( category, code, desc == null ? "" : desc, extDesc ); fError = error; } /** * Gets all SIF_Errors wrapped by this exception * @return an array of SIF_Error elements */ public SIF_Error getError() { return fError; } /** * Determines if this SIFException describes any SIF_Errors * @return true if the exception wraps at least on SIF_Error */ public boolean hasErrors() { return fError != null; } /** * Determines if this SIFException has an error with the specified category * and code. In some versions of SIF, a SIFException may describe more than * one error. This method searches through all of the wrapped errors and * returns <code>true</code> if any match the category and code.<p> * * @deprecated Please use the overload of this method that takes a SIFErrorCategory * as the first parameter * * @param category The SIF error category to search for * @param code The SIF error code to search for * * @return <code>true</code> if any errors wrapped by this exception match * the category and code */ public boolean hasError( int category, int code ) { if( fError != null ) { if( fError.getSIF_Category() == category && fError.getSIF_Code() == code ) { return true; } } return false; } /** * Determines if this SIFException has an error with the specified category * and code. In some versions of SIF, a SIFException may describe more than * one error. This method searches through all of the wrapped errors and * returns <code>true</code> if any match the category and code.<p> * * @param category The SIF error category to search for * @param code The SIF error code to search for * * @return <code>true</code> if any errors wrapped by this exception match * the category and code */ public boolean hasError( SIFErrorCategory category, int code ) { if( fError != null ) { if( SIFErrorCategory.lookup( fError.getSIF_Category() ) == category && fError.getSIF_Code() == code ) { return true; } } return false; } /** * Determines if this SIFException has an error with the specified category. * In some versions of SIF, a SIFException may describe more than * one error. This method searches through all of the wrapped errors and * returns <code>true</code> if any match the category.<p> * * @deprecated please use the overload that takes a SIFErrorCategory * * @param category The SIF error category to search for * * @return <code>true</code> if any errors wrapped by this exception match * the category */ public boolean hasErrorCategory( int category ) { if( fError != null ) { return fError.getSIF_Category() == category; } return false; } /** * Determines if this SIFException has an error with the specified category. * In some versions of SIF, a SIFException may describe more than * one error. This method searches through all of the wrapped errors and * returns <code>true</code> if any match the category.<p> * * @param category The SIF error category to search for * * @return <code>true</code> if any errors wrapped by this exception match * the category */ public boolean hasErrorCategory( SIFErrorCategory category ) { return category == getSIFErrorCategory(); } /** * Sets the SIF_Error element associated with this exception. * @param category A <code>SIFErrorCodes.CAT_</code> error category * @param code A <code>SIFErrorCodes_</code> error code * @param desc * @param extDesc */ public void setSIF_Error( int category, int code, String desc, String extDesc ) { fError = new SIF_Error( category, code, desc, extDesc ); } /** * Sets the SIF_Error element associated with this exception. * @param category The category associated with this error * @param code A <code>SIFErrorCodes_</code> error code * @param desc * @param extDesc */ public void setSIF_Error( SIFErrorCategory category, int code, String desc, String extDesc ) { fError = new SIF_Error( category, code, desc, extDesc ); } private void _checkErrorExists() { if( fError == null ){ fError = new SIF_Error(); } } /** * Sets the error category code of the first SIF_Error wrapped by this * exception. If no SIF_Errors are wrapped by this exception, a new one * is created.<p> * * @param category A <code>SIFErrorCodes.CAT_</code> error category */ public void setErrorCategory( int category ) { _checkErrorExists(); fError.setSIF_Category( category ); } /** * Sets the error category code of the first SIF_Error wrapped by this * exception. If no SIF_Errors are wrapped by this exception, a new one * is created.<p> * * @param category The category to set to this exception */ public void setErrorCategory( SIFErrorCategory category ) { _checkErrorExists(); fError.setSIF_Category( category.getValue() ); } /** * Sets the error code of the first SIF_Error wrapped by this exception. * If no SIF_Errors are wrapped by this exception, a new one is created.<p> * * @param code A <code>SIFErrorCodes</code> error code */ public void setErrorCode( int code ) { _checkErrorExists(); fError.setSIF_Code( code ); } /** * Sets the error description of the first SIF_Error wrapped by this * exception. If no SIF_Errors are wrapped by this exception, a new one * is created.<p> * * @param desc The error description */ public void setErrorDesc( String desc ) { _checkErrorExists(); fError.setSIF_Desc( desc ); } /** * Sets the optional extended error description of the first SIF_Error * wrapped by this exception. If no SIF_Errors are wrapped by this exception, * a new one is created.<p> * * @param extDesc The extended error description */ public void setErrorExtDesc( String extDesc ) { _checkErrorExists(); fError.setSIF_ExtendedDesc( extDesc ); } /** * Gets the Error Category of the first SIF_Error element, or 0xFFFFFFFF * if there are no errors. * @deprecated Please use getSIFErrorCategory * @return The Category associated with this error */ public int getErrorCategory() { if( fError != null ){ return fError.getSIF_Category(); } return 0xFFFFFFFF; } /** * Gets the Error Category of the first SIF_Error element, or 0xFFFFFFFF * if there are no errors. * @return The Category associated with this error */ public SIFErrorCategory getSIFErrorCategory() { if( fError != null ){ return SIFErrorCategory.lookup( fError.getSIF_Category() ); } return SIFErrorCategory.UNKNOWN; } /** * Gets the Error Code of the first SIF_Error element, or 0xFFFFFFFF * if there are no errors. * @return The Code associated with this error */ public int getErrorCode() { if( fError != null ){ return fError.getSIF_Code(); } return 0xFFFFFFFF; } /** * Gets the Error Description of the first SIF_Error element, or null * if there are no errors. * @return The description of the error */ public String getErrorDesc() { if( fError != null ){ return fError.getSIF_Desc(); } return null; } /** * Gets the Extended Error Description of the first SIF_Error element, or * null if there are no errors. * @return The extended error description */ public String getErrorExtDesc() { if( fError != null ){ return fError.getSIF_ExtendedDesc(); } return null; } /** * The SIF_Ack that is part of this exception * @return The SIF_Ack that is part of this exception */ public SIF_Ack getAck() { return fAck; } /* (non-Javadoc) * @see java.lang.Throwable#getMessage() */ public String getMessage() { StringBuffer buf = new StringBuffer(); String msg = super.getMessage(); if( msg != null ) { // Only include super.getMessage() text if there is no SIF_Error or // if there is a SIF_Error and its SIF_Desc text is different. This // makes for much less annoying error output. if( fError == null || ( fError.getSIF_Desc() != null && !fError.getSIF_Desc().equals(msg) ) ) { buf.append(msg); buf.append(": "); } } if( fError != null ) { buf.append("[Category="); buf.append(fError.getSIF_Category()); buf.append("; Code="); buf.append(fError.getSIF_Code()); buf.append("] "); String desc = fError.getSIF_Desc(); if( desc != null ) buf.append( desc ); desc = fError.getSIF_ExtendedDesc(); if( desc != null ) { buf.append(". "); buf.append( desc ); } } return buf.toString(); } }