/**
*#########################################################################
* FedoraGS3Exception.java - works with the demo-client for Greenstone 3,
* of the Greenstone digital library suite from the New Zealand Digital
* Library Project at the * University of Waikato, New Zealand.
*
* Copyright (C) 2008 New Zealand Digital Library Project
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*########################################################################
*/
package org.greenstone.fedora.services;
import java.io.IOException;
import java.io.UnsupportedEncodingException;
import java.rmi.RemoteException;
import org.apache.log4j.Logger;
import org.greenstone.gsdl3.util.GSXML;
import org.xml.sax.SAXException;
/**
* The exceptions that can be thrown by FedoraGS3. This class
* represents a general FedoraGS3 exception. It will LOG the
* exceptions for all the (static inner) subclasses. And, through
* the Cause object, also for the static inner Exception classes
* that do not inherit but are encapsulated in subclass
* FedoraGS3RunException when its constructor is called with the
* particular Exception type. The 'Cause' Exception classes therefore
* indicate the root causes for why a FedoraGS3RunException was thrown.
* @author ak19
*/
public class FedoraGS3Exception extends Exception {
/** Constant string message to display when a connection is refused */
public static final String connectionRefusedMessage
= "\nUnable to connect. Either the host"
+ " and/or port contain invalid values\nOR the fedora"
+ " server at that location is down/not yet running."
+ "\nTry once more by changing the values for host or port.";
/** Constant string message to display if the sslHandshake fails
* when trying to connect to Fedora using https */
public static final String sslHandshakeExceptionMessage
= "SSLHandshakeException.\nThe protocol 'https' might be"
+ "incorrect.\nTry once more. Perhaps with 'http' instead.";
/** Constant string message to check against if "AXIS engine
* could not find a target service to invoke" message is the cause
* for an AxisFault exception embedded in a RemoteException */
public static final String missingTargetService
= "could not find a target service to invoke";
/** The logging instance for this class */
private static final Logger LOG = Logger.getLogger(
FedoraGS3Exception.class.getName());
/** No argument constructor merely sets the message to
* this class' name. */
public FedoraGS3Exception(){
super("FedoraGS3Exception");
if(this.getMessage() != null) {
LOG.error("Message: " + this.getMessage());
}
if(this.getCause() != null) {
LOG.error("Cause: " + this.getCause().getMessage());
}
LOG.debug(this); // stacktrace
}
/** Constructs a FedoraGS3Exception with the given message.
* @param message is an information String of what went wrong. */
public FedoraGS3Exception(String message){
super(message);
if(this.getMessage() != null) {
LOG.error("Message: " + this.getMessage());
}
if(this.getCause() != null) {
LOG.error("Cause: " + this.getCause().getMessage());
}
LOG.debug(this); // stacktrace
}
/** Constructs a FedoraGS3Exception with the given message and cause.
* @param message is an information String of what went wrong.
* @param cause is a Throwable object (perhaps another Exception)
* of what caused this exception to occur. */
public FedoraGS3Exception(String message, Throwable cause) {
super(message, cause);
if(this.getMessage() != null) {
LOG.error("Message: " + this.getMessage());
}
if(this.getCause() != null) {
LOG.error("Cause: " + this.getCause().getMessage());
}
LOG.debug(this); // stacktrace
}
/** Constructs a FedoraGS3Exception with the given cause.
* @param cause is a Throwable object (perhaps another Exception)
* of what caused this exception to occur. */
public FedoraGS3Exception(Throwable cause) {
super("FedoraGS3Exception", cause);
if(this.getMessage() != null) {
LOG.error("Message: " + this.getMessage());
}
if(this.getCause() != null) {
LOG.error("Cause: " + this.getCause().getMessage());
}
LOG.debug(this); // stacktrace
}
/** Represents an exception that occurs when FedoraGS3 is running
* A subclass of FedoraGS3Exception */
public static class FedoraGS3RunException extends FedoraGS3Exception {
/** If a problem occurs converting the error message into XML
* this string is created in the format of XML stating the
* problem that occurred when trying to convert XML to String. */
protected static String xmlToStringConversionFailureResponseMsg;
/** Some extra information as to what when wrong */
protected String specifics = "";
static {
StringBuffer buf = new StringBuffer("<" + GSXML.MESSAGE_ELEM + ">");
buf.append("<" + GSXML.RESPONSE_ELEM + " "
+ GSXML.FROM_ATT + "=\"" + "FedoraGS3\"" + ">");
buf.append("<" + GSXML.ERROR_ELEM + " "
+ GSXML.ERROR_TYPE_ATT + "=\""+ GSXML.ERROR_TYPE_OTHER + "\"" + ">");
buf.append("(TransformerException): trouble converting original XML "
+ "response message into String.");
buf.append("" + GSXML.ERROR_ELEM + ">");
buf.append("" + GSXML.RESPONSE_ELEM + ">");
buf.append("" + GSXML.MESSAGE_ELEM + ">");
xmlToStringConversionFailureResponseMsg = buf.toString();
//System.err.println(xmlToStringConversionFailureResponseMsg);
}
public FedoraGS3RunException() {
super("FedoraGS3RunException");
}
public FedoraGS3RunException(String message){
super(message);
}
public FedoraGS3RunException(String message, Throwable cause) {
super("FedoraGS3RunException " + message, cause);
}
public FedoraGS3RunException(Throwable cause) {
super("Caused by "
+ cause.getClass() + ":\n" + cause.getMessage(), cause);
}
public void setSpecifics(String specifics) {
this.specifics = specifics;
}
/** Overloading getMessage() to return some details as to what
* exactly went wrong. */
public String getMessage() {
String msg = "";
Throwable cause = this.getCause();
if(cause == null)
return super.getMessage();
if(cause instanceof RemoteException) {
// specifically indicate it's a RemoteException (as it encapsulates
// different exception classes)
msg = "(RemoteException): problem invoking web service";
if(specifics != null && !specifics.equals("")) {
msg += ", possibly trouble finding " + specifics;
}
// Some info on what caused the Remote Exception:
msg += ".\nCause: " + cause.getMessage();
} else { // Other kind of cause to exception:
if(cause instanceof UnsupportedEncodingException) {
msg = "(UnsupportedEncodingException): trouble converting "
+ specifics + "returned "
+ "from Fedora web services to " + FedoraConnection.UTF8;
} else if(cause instanceof SAXException) {
msg = "(SAXException): trouble parsing "
+ specifics + " returned from web service";
} else if(cause instanceof IOException) {
msg = "(IOException): trouble parsing "
+ specifics + " returned from web service";
} /*else if(cause instanceof TransformerException) {
msg = msg + "(TransformerException) - trouble converting original XML "
+ "response into String";
}*/
// else (other Exception, including FedoraVersionNotSupportedException)
// in those cases, just return it as it is.
// else msg = "";
if(!msg.equals(""))
msg = " " + msg + ". ";
}
return this.getClass().getCanonicalName()
+ msg + super.getMessage();
}
}
/** Static inner class FedoraGS3InitFailureException is an Exception
* that is thrown when no connection can be made to the Fedora server
* and therefore the FedoraGS3 object construction failed.
* Its constructor allows other exceptions to be encapsulated within
* it, via the cause object (a Throwable, superclass of Exception)
* parameter. This (the actual exception that caused the
* FedoraGS3InitFailureException) can be queried by interested parties
* via the getCause() method. */
public static class FedoraGS3InitFailureException extends FedoraGS3Exception {
public static final String MESSAGE =
"Unable to instantiate FedoraToGS3Interface";
public FedoraGS3InitFailureException(){ super(MESSAGE); }
public FedoraGS3InitFailureException(String message){ super(message); }
public FedoraGS3InitFailureException(String message, Throwable cause) {
super(message, cause);
}
public FedoraGS3InitFailureException(Throwable cause) {
super(MESSAGE+ " due to exception "
+ cause.getClass() + ":\n" + cause.getMessage(), cause);
}
}
//***************** FEDORA CONNECTION EXCEPTIONS**********************/
/**
* When the user chooses to cancel out of the FedoraConnection dialog of
* the constructor (where they have to enter authentication information),
* this exception is thrown, so that classes making use of FedoraConnection
* may choose whether to exit their program or deal with it differently.
* */
public static class CancelledException extends Exception {
public CancelledException() {
super("User cancelled out of connecting to Fedora.\n"
+ "Cannot instantiate FedoraConnection.\n");
}
}
/**
* This AuthenticationFailedException can be thrown when the user enters
* an invalid username and password into the FedoraConnection Authentication
* popup dialog (displayed upon FedoraConnection object construction).
*/
public static class AuthenticationFailedException extends Exception {
public AuthenticationFailedException() {
super("(401) Incorrect username and/or password. "
+ "Please re-enter values.");
}
}
/**
* This ServerNotFoundException can be thrown when the user enters
* there is no (Fedora) server listening at a given host and port.
* Thrown when a 404 Not Found occurs.
*/
public static class ServerNotFoundException extends Exception {
public ServerNotFoundException(String message) {
super(message);
}
}
/**
* This AuthenticationFailedException can be thrown when there is some
* server listening at the host and port values entered by the user, but
* when this server is (most likely) not a Fedora Server.
* The IOException message received in such cases is:
* "Unable to instantiate FedoraConnection
* java.io.IOException: Request failed [404 /fedora/describe]"
* And in such cases, we can throw this NotAFedoraServerException
* to deal with it more particularly than more general IOExceptions.
*/
public static class NotAFedoraServerException extends Exception {
public static final String MESSAGE =
"There is a server listening at the given host and port,"
+ "\nbut it does not seem to be a Fedora server."
+ "\nTry changing the host and/or port values.";
public NotAFedoraServerException() {
super(MESSAGE);
}
public NotAFedoraServerException(String message) {
super(MESSAGE + ":\n(" + message + ")");
}
}
/**
* Certain functionality in Fedora - in particular fielded search - is
* implemented differently or uses slightly different Fedora types in older
* versions of Fedora (fielded search in 2.0 uses a different Condition class).
* In that case, the fielded search web service cannot be performed, and
* this FedoraVersionNotSupportedException is thrown.
*/
public static class FedoraVersionNotSupportedException extends Exception {
public FedoraVersionNotSupportedException(String fedoraVersion) {
super("Fedora repository version is " + fedoraVersion
+ "\nHowever, browsing/searching by field only works "
+ "from version " + FedoraConnection.SUPPORTED_VERSION + " onwards.");
}
}
}