/******************************************************************************* * Copyright (c) 2007, 2014 compeople AG and others. * All rights reserved. This program and the accompanying materials * are made available under the terms of the Eclipse Public License v1.0 * which accompanies this distribution, and is available at * http://www.eclipse.org/legal/epl-v10.html * * Contributors: * compeople AG - initial API and implementation *******************************************************************************/ package org.eclipse.riena.internal.core.exceptionmanager; import java.util.List; import org.osgi.service.log.LogService; import org.eclipse.core.runtime.IStatus; import org.eclipse.core.runtime.jobs.IJobChangeEvent; import org.eclipse.core.runtime.jobs.IJobChangeListener; import org.eclipse.core.runtime.jobs.IJobManager; import org.eclipse.core.runtime.jobs.JobChangeAdapter; import org.eclipse.equinox.log.Logger; import org.eclipse.riena.core.Log4r; import org.eclipse.riena.core.exception.IExceptionHandler; import org.eclipse.riena.core.exception.IExceptionHandlerManager; import org.eclipse.riena.core.injector.InjectionFailure; import org.eclipse.riena.core.util.Orderer; import org.eclipse.riena.core.util.StringUtils; import org.eclipse.riena.core.wire.InjectExtension; import org.eclipse.riena.core.wire.InjectService; import org.eclipse.riena.internal.core.Activator; /** * A simple implementation of a {@code IExceptionHandlerManager}.<br> * This exception handler manager asks the configured {@code IExceptionHandler}s * whether they can handle a given exception, e.g. display the exception in * dialog or log it.<br> * Additionally it listens for exceptions thrown within {@code Job}s and handles * them. */ public class SimpleExceptionHandlerManager implements IExceptionHandlerManager { private List<IExceptionHandler> handlers; private final IJobChangeListener jobChangeListener = new JobChangeListener(); private final static Logger LOGGER = Log4r.getLogger(Activator.getDefault(), SimpleExceptionHandlerManager.class); @InjectExtension public void update(final IExceptionHandlerExtension[] exceptionHandlerExtensions) { final Orderer<IExceptionHandler> orderer = new Orderer<IExceptionHandler>(); for (final IExceptionHandlerExtension extension : exceptionHandlerExtensions) { orderer.add(extension.createExceptionHandler(), extension.getName(), extension.getPreHandlers(), getPostHandler(extension)); } handlers = orderer.getOrderedObjects(); } @InjectService public void bind(final IJobManager jobManager) { jobManager.addJobChangeListener(jobChangeListener); } public void unbind(final IJobManager jobManager) { jobManager.removeJobChangeListener(jobChangeListener); } /** * Handle the transition from deprecated 'before' to new 'postHandler'. */ @SuppressWarnings("deprecation") private String getPostHandler(final IExceptionHandlerExtension extension) { if (StringUtils.isGiven(extension.getBefore()) && StringUtils.isGiven(extension.getPostHandlers())) { throw new InjectionFailure( "ExcetionHandler definition " //$NON-NLS-1$ + extension.getName() + "uses both the deprecated 'before' and new 'getPostHandler' attributes. Use only 'getPostHandler'"); //$NON-NLS-1$ } if (StringUtils.isGiven(extension.getBefore())) { return extension.getBefore(); } if (StringUtils.isGiven(extension.getPostHandlers())) { return extension.getPostHandlers(); } return null; } public IExceptionHandler.Action handleException(final Throwable t) { return handleException(t, null, LOGGER); } public IExceptionHandler.Action handleException(final Throwable t, final Logger logger) { return handleException(t, null, logger); } public IExceptionHandler.Action handleException(final Throwable t, final String msg) { return handleException(t, msg, LOGGER); } public IExceptionHandler.Action handleException(final Throwable t, final String msg, final Logger logger) { for (final IExceptionHandler handler : handlers) { try { final IExceptionHandler.Action action = handler.handleException(t, msg, logger); if (action != IExceptionHandler.Action.NOT_HANDLED) { return action; } } catch (final Throwable t2) { // if an exception handler throws an exception there is nothing we can do, log problem and try the next exception handler LOGGER.log(LogService.LOG_ERROR, "exception handler " + handler.getClass() //$NON-NLS-1$ + "#handleException() throws an exception", t2); //$NON-NLS-1$ } } return IExceptionHandler.Action.NOT_HANDLED; } private class JobChangeListener extends JobChangeAdapter { @Override public void done(final IJobChangeEvent event) { final IStatus result = event.getResult(); if (result != null && result.getSeverity() == IStatus.ERROR && result.getException() != null) { handleException(result.getException(), result.getMessage()); } } } }