/*
* Copyright 1999-2006 University of Chicago
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.dcache.ftp.client.exception;
/**
* Most exceptions used by ftp package are subclasses of FTPException and inherit its features:
* <p>
* <ul>
* <li> exception code can be used to more precisely identify the problem. Exception codes are defined within each exception class (look at the source code). For example, in ClientException, code 8 (ClientException.BAD_MODE) indicates that client refused operation because of bad transfer mode, while code 13 (ClientException.BAD_TYPE) indicates that the same thing was caused by bad transfer type. To programmatically retrieve the exception code, use exception.getCode().
* <p>
* <li> exception nesting can be used to track the root of the exceptions that come from lower software layers. Use getRootCause().
* </ul>
*/
public class FTPException extends Exception
{
private static final long serialVersionUID = -7860725803672334029L;
public static final int UNSPECIFIED = 0;
protected int code = UNSPECIFIED;
private static final String[] codeExplained = {"Unspecified category."};
public String getCodeExplanation(int code)
{
if (codeExplained.length > code)
return codeExplained[code];
else return "";
}
//the exception that caused this exception, if any
protected Exception cause;
//this message is not just explanation of the code.
//it is a custom message informing of particular
//conditions of the error.
protected String customMessage;
public FTPException(int code, String message)
{
super();
this.code = code;
customMessage = message;
}
public FTPException(int code)
{
this.code = code;
}
public void setRootCause(Exception c)
{
this.cause = c;
}
/**
* Retrieve the nested lower layer exception.
*/
public Exception getRootCause()
{
return cause;
}
public void setCode(int c)
{
this.code = c;
}
public int getCode()
{
return code;
}
public void setCustomMessage(String m)
{
customMessage = m;
}
public String getCustomMessage()
{
return customMessage;
}
//overwriting inherited
@Override
public String getMessage()
{
StringBuilder buf = new StringBuilder();
if (code != UNSPECIFIED) {
buf.append(getCodeExplanation(code));
}
if (customMessage != null) {
buf.append(" Custom message: ");
buf.append(customMessage);
}
if (code != UNSPECIFIED) {
buf.append(" (error code ").append(String.valueOf(code)).append(")");
}
if (cause != null) {
buf.append(" [Nested exception message: ");
buf.append(cause.getMessage());
buf.append("]");
}
return buf.toString();
}
public String toString()
{
String answer = super.toString();
if (cause != null && cause != this) {
answer += " [Nested exception is " + cause.toString() + "]";
}
return answer;
}
@Override
public void printStackTrace()
{
printStackTrace(System.err);
}
@Override
public void printStackTrace(java.io.PrintStream ps)
{
if (cause != null) {
String superString = super.toString();
synchronized (ps) {
ps.print(superString
+ (superString.endsWith(".") ? "" : ".")
+ " Nested exception is ");
cause.printStackTrace(ps);
}
} else {
super.printStackTrace(ps);
}
}
@Override
public void printStackTrace(java.io.PrintWriter pw)
{
if (cause != null) {
String superString = super.toString();
synchronized (pw) {
pw.print(superString
+ (superString.endsWith(".") ? "" : ".")
+ " Nested exception is ");
cause.printStackTrace(pw);
}
} else {
super.printStackTrace(pw);
}
}
}