| /******************************************************************************* |
| * Copyright (c) 2009, 2011 Cloudsmith Inc, and other. |
| * The code, documentation and other materials contained herein have been |
| * licensed under the Eclipse Public License - v 1.0 by the individual |
| * copyright holders listed above, as Initial Contributors under such license. |
| * The text of such license is available at www.eclipse.org. |
| * Contributors: |
| * Cloudsmith Inc. - Initial API and implementation |
| * IBM Corporation - Original Implementation of checkPermissionDenied |
| * IBM Corportaion - Ongoing development |
| *******************************************************************************/ |
| package org.eclipse.equinox.internal.p2.transport.ecf; |
| |
| import java.io.FileNotFoundException; |
| import java.io.IOException; |
| import java.io.PrintStream; |
| import java.lang.reflect.InvocationTargetException; |
| import java.net.URI; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IStatus; |
| import org.eclipse.core.runtime.OperationCanceledException; |
| import org.eclipse.core.runtime.Status; |
| import org.eclipse.ecf.filetransfer.BrowseFileTransferException; |
| import org.eclipse.ecf.filetransfer.IncomingFileTransferException; |
| import org.eclipse.equinox.internal.p2.repository.AuthenticationFailedException; |
| import org.eclipse.equinox.internal.p2.repository.JREHttpClientRequiredException; |
| import org.eclipse.equinox.p2.core.ProvisionException; |
| import org.eclipse.osgi.util.NLS; |
| |
| /** |
| * RepositoryStatusHelper is a utility class for processing of exceptions and status. |
| */ |
| public abstract class RepositoryStatusHelper { |
| |
| protected static final String SERVER_REDIRECT = "Server redirected too many times"; //$NON-NLS-1$ |
| |
| public static IStatus createStatus(String nlsMessage, Object arg) { |
| return createExceptionStatus(null, nlsMessage, new Object[] {arg}); |
| } |
| |
| public static IStatus createStatus(String nlsMessage, Object arg1, Object arg2) { |
| return createExceptionStatus(null, nlsMessage, new Object[] {arg1, arg2}); |
| } |
| |
| public static IStatus createStatus(String nlsMessage, Object arg1, Object arg2, Object arg3) { |
| return createExceptionStatus(null, nlsMessage, new Object[] {arg1, arg2, arg3}); |
| } |
| |
| public static IStatus createStatus(String nlsMessage, Object[] args) { |
| return createExceptionStatus(null, nlsMessage, args); |
| } |
| |
| public static IStatus createStatus(String nlsMessage) { |
| return createExceptionStatus(null, nlsMessage, new Object[] {}); |
| } |
| |
| public static IStatus createExceptionStatus(Throwable cause) { |
| return (cause instanceof CoreException) ? ((CoreException) cause).getStatus() : new Status(IStatus.ERROR, Activator.ID, IStatus.OK, cause.getMessage(), cause); |
| } |
| |
| public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object[] args) { |
| if (args != null && args.length > 0) |
| nlsMessage = NLS.bind(nlsMessage, args); |
| return new Status(IStatus.ERROR, Activator.ID, IStatus.OK, nlsMessage, cause); |
| } |
| |
| public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object arg1, Object arg2, Object arg3) { |
| return createExceptionStatus(cause, nlsMessage, new Object[] {arg1, arg2, arg3}); |
| } |
| |
| public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object arg1, Object arg2) { |
| return createExceptionStatus(cause, nlsMessage, new Object[] {arg1, arg2}); |
| } |
| |
| public static IStatus createExceptionStatus(Throwable cause, String nlsMessage, Object arg1) { |
| return createExceptionStatus(cause, nlsMessage, new Object[] {arg1}); |
| } |
| |
| public static IStatus createExceptionStatus(Throwable cause, String nlsMessage) { |
| return createExceptionStatus(cause, nlsMessage, new Object[] {}); |
| } |
| |
| public static void deeplyPrint(Throwable e, PrintStream strm, boolean stackTrace) { |
| deeplyPrint(e, strm, stackTrace, 0); |
| } |
| |
| public static CoreException fromMessage(String nlsMessage, Object[] args) { |
| return fromExceptionMessage(null, nlsMessage, args); |
| } |
| |
| public static CoreException fromMessage(String nlsMessage, Object arg1) { |
| return fromExceptionMessage(null, nlsMessage, new Object[] {arg1}); |
| } |
| |
| public static CoreException fromMessage(String nlsMessage, Object arg1, Object arg2) { |
| return fromExceptionMessage(null, nlsMessage, new Object[] {arg1, arg2}); |
| } |
| |
| public static CoreException fromMessage(String nlsMessage, Object arg1, Object arg2, Object arg3) { |
| return fromExceptionMessage(null, nlsMessage, new Object[] {arg1, arg2, arg3}); |
| } |
| |
| public static CoreException fromMessage(String nlsMessage) { |
| return fromExceptionMessage(null, nlsMessage, new Object[] {}); |
| } |
| |
| public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object[] args) { |
| CoreException ce = new CoreException(createExceptionStatus(cause, nlsMessage, args)); |
| if (cause != null) |
| ce.initCause(cause); |
| return ce; |
| } |
| |
| public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object arg1, Object arg2, Object arg3) { |
| return fromExceptionMessage(cause, nlsMessage, new Object[] {arg1, arg2, arg3}); |
| } |
| |
| public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object arg1, Object arg2) { |
| return fromExceptionMessage(cause, nlsMessage, new Object[] {arg1, arg2}); |
| } |
| |
| public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage, Object arg1) { |
| return fromExceptionMessage(cause, nlsMessage, new Object[] {arg1}); |
| } |
| |
| public static CoreException fromExceptionMessage(Throwable cause, String nlsMessage) { |
| return fromExceptionMessage(cause, nlsMessage, new Object[] {}); |
| } |
| |
| public static Throwable unwind(Throwable t) { |
| for (;;) { |
| Class<? extends Throwable> tc = t.getClass(); |
| |
| // We don't use instanceof operator since we want |
| // the explicit class, not subclasses. |
| // |
| if (tc != RuntimeException.class && tc != InvocationTargetException.class && tc != IOException.class) |
| break; |
| |
| Throwable cause = t.getCause(); |
| if (cause == null) |
| break; |
| |
| String msg = t.getMessage(); |
| if (msg != null && !msg.equals(cause.toString())) |
| break; |
| |
| t = cause; |
| } |
| return t; |
| } |
| |
| public static CoreException unwindCoreException(CoreException exception) { |
| IStatus status = exception.getStatus(); |
| while (status != null && status.getException() instanceof CoreException) { |
| exception = (CoreException) status.getException(); |
| status = exception.getStatus(); |
| } |
| return exception; |
| } |
| |
| public static CoreException wrap(IStatus status) { |
| CoreException e = new CoreException(status); |
| Throwable t = status.getException(); |
| if (t != null) |
| e.initCause(t); |
| return e; |
| } |
| |
| public static CoreException wrap(Throwable t) { |
| t = unwind(t); |
| if (t instanceof CoreException) |
| return unwindCoreException((CoreException) t); |
| |
| if (t instanceof OperationCanceledException || t instanceof InterruptedException) |
| return new CoreException(Status.CANCEL_STATUS); |
| |
| String msg = t.toString(); |
| return fromExceptionMessage(t, msg); |
| } |
| |
| private static void appendLevelString(PrintStream strm, int level) { |
| if (level > 0) { |
| strm.print("[0"); //$NON-NLS-1$ |
| for (int idx = 1; idx < level; ++idx) { |
| strm.print('.'); |
| strm.print(level); |
| } |
| strm.print(']'); |
| } |
| } |
| |
| private static void deeplyPrint(CoreException ce, PrintStream strm, boolean stackTrace, int level) { |
| appendLevelString(strm, level); |
| if (stackTrace) |
| ce.printStackTrace(strm); |
| deeplyPrint(ce.getStatus(), strm, stackTrace, level); |
| } |
| |
| private static void deeplyPrint(IStatus status, PrintStream strm, boolean stackTrace, int level) { |
| appendLevelString(strm, level); |
| String msg = status.getMessage(); |
| strm.println(msg); |
| Throwable cause = status.getException(); |
| if (cause != null) { |
| strm.print("Caused by: "); //$NON-NLS-1$ |
| if (stackTrace || !(msg.equals(cause.getMessage()) || msg.equals(cause.toString()))) |
| deeplyPrint(cause, strm, stackTrace, level); |
| } |
| |
| if (status.isMultiStatus()) { |
| IStatus[] children = status.getChildren(); |
| for (IStatus child : children) { |
| deeplyPrint(child, strm, stackTrace, level + 1); |
| } |
| } |
| } |
| |
| private static void deeplyPrint(Throwable t, PrintStream strm, boolean stackTrace, int level) { |
| if (t instanceof CoreException) |
| deeplyPrint((CoreException) t, strm, stackTrace, level); |
| else { |
| appendLevelString(strm, level); |
| if (stackTrace) |
| t.printStackTrace(strm); |
| else { |
| strm.println(t.toString()); |
| Throwable cause = t.getCause(); |
| if (cause != null) { |
| strm.print("Caused by: "); //$NON-NLS-1$ |
| deeplyPrint(cause, strm, stackTrace, level); |
| } |
| } |
| } |
| } |
| |
| /** |
| * Check if the given exception represents that a switch to the JRE HTTP Client |
| * is required. ECF sets the HTTP status code 477 to indicate this. |
| * If the JRE HTTP client is required a JREHttpClientRequiredException is thrown. |
| */ |
| public static void checkJREHttpClientRequired(Throwable t) throws JREHttpClientRequiredException { |
| if (t instanceof IncomingFileTransferException) { |
| if (((IncomingFileTransferException) t).getErrorCode() == 477) |
| throw new JREHttpClientRequiredException(); |
| } else if (t instanceof BrowseFileTransferException) { |
| if (((BrowseFileTransferException) t).getErrorCode() == 477) |
| throw new JREHttpClientRequiredException(); |
| } |
| |
| } |
| |
| /** |
| * Check if the given exception represents a permission failure (401 for HTTP), |
| * and throw a AuthenticationFailedException if a permission failure was encountered. |
| */ |
| public static void checkPermissionDenied(Throwable t) throws AuthenticationFailedException { |
| // From Use of File Transfer |
| if (t instanceof IncomingFileTransferException) { |
| if (((IncomingFileTransferException) t).getErrorCode() == 401) |
| throw new AuthenticationFailedException(); |
| IStatus status = ((IncomingFileTransferException) t).getStatus(); |
| t = status == null ? t : status.getException(); |
| // From Use of Browse |
| } else if (t instanceof BrowseFileTransferException) { |
| if (((BrowseFileTransferException) t).getErrorCode() == 401) |
| throw new AuthenticationFailedException(); |
| IStatus status = ((BrowseFileTransferException) t).getStatus(); |
| t = status == null ? t : status.getException(); |
| } |
| |
| if (t == null || !(t instanceof IOException)) |
| return; |
| |
| // TODO: is this needed (for 401) now that ECF throws exceptions with codes? |
| // try to figure out if we have a 401 by parsing the exception message |
| // There is unfortunately no specific (general) exception for "redirected too many times" - which is commonly |
| // caused by a failed login. The message and exception are different in different implementations |
| // of http client. |
| String m = t.getMessage(); |
| if (m != null && (m.contains(" 401 ") || m.contains(SERVER_REDIRECT))) //$NON-NLS-1$ |
| throw new AuthenticationFailedException(); |
| if ("org.apache.commons.httpclient.RedirectException".equals(t.getClass().getName())) //$NON-NLS-1$ |
| throw new AuthenticationFailedException(); |
| } |
| |
| /** |
| * Translates exceptions representing "FileNotFound" into FileNotFoundException. |
| * @param t the throwable to check |
| * @param toDownload the URI the exception was thrown for |
| * @throws FileNotFoundException if 't' represents a file not found |
| */ |
| public static void checkFileNotFound(Throwable t, URI toDownload) throws FileNotFoundException { |
| if (t instanceof IncomingFileTransferException) { |
| IncomingFileTransferException e = (IncomingFileTransferException) t; |
| if (e.getErrorCode() == 404 || e.getErrorCode() == 403 || e.getErrorCode() == 300) |
| throw new FileNotFoundException(toDownload.toString()); |
| } |
| if (t instanceof BrowseFileTransferException) { |
| BrowseFileTransferException e = (BrowseFileTransferException) t; |
| if (e.getErrorCode() == 404 || e.getErrorCode() == 403 || e.getErrorCode() == 300) |
| throw new FileNotFoundException(toDownload.toString()); |
| } |
| |
| if (t instanceof FileNotFoundException) |
| throw (FileNotFoundException) t; |
| if (t instanceof CoreException) { |
| IStatus status = ((CoreException) t).getStatus(); |
| Throwable e = status == null ? null : status.getException(); |
| if (e instanceof FileNotFoundException) |
| throw (FileNotFoundException) e; |
| } |
| } |
| |
| public static IStatus malformedAddressStatus(String address, Throwable t) { |
| return new Status(IStatus.ERROR, Activator.ID, // |
| ProvisionException.REPOSITORY_INVALID_LOCATION, NLS.bind(Messages.exception_malformedRepoURI, address), t); |
| |
| } |
| } |