/** * * Copyright * 2009-2015 Jayway Products AB * 2016-2017 Föreningen Sambruk * * Licensed under AGPL, Version 3.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.gnu.org/licenses/agpl.txt * * 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 se.streamsource.streamflow.client.util; import org.jdesktop.swingx.JXDialog; import org.jdesktop.swingx.JXErrorPane; import org.jdesktop.swingx.error.ErrorInfo; import org.qi4j.api.injection.scope.Service; import org.restlet.data.Status; import org.restlet.resource.ResourceException; import se.streamsource.streamflow.api.ErrorResources; import se.streamsource.streamflow.client.OperationException; import se.streamsource.streamflow.client.StreamflowApplication; import se.streamsource.streamflow.client.StreamflowResources; import se.streamsource.streamflow.client.util.dialog.DialogService; import javax.swing.JLabel; import javax.swing.JOptionPane; import javax.swing.SwingUtilities; import java.awt.Component; import java.awt.Dimension; import java.awt.EventQueue; import java.awt.Frame; import java.lang.reflect.InvocationTargetException; import java.util.Collections; import java.util.logging.Level; import static se.streamsource.streamflow.client.util.i18n.*; /** * JAVADOC */ public class UncaughtExceptionHandler implements Thread.UncaughtExceptionHandler { private @Service StreamflowApplication main; private @Service DialogService dialogs; private boolean processing = false; public void uncaughtException(Throwable e) { uncaughtException(Thread.currentThread(), e); } public void uncaughtException(Thread t, final Throwable e) { final Throwable ex = unwrap(e); Object source = null; try { source = EventQueue.getCurrentEvent().getSource(); } catch (NullPointerException npe) { // STREAMFLOW-75 Unchaught exception visitor does not popup on // Windows // therefor we have to consume any nullpointer here to be able to // continue } final Frame frame = source instanceof Component ? (Frame) SwingUtilities.getAncestorOfClass(Frame.class, (Component) source) : main.getMainFrame(); SwingUtilities.invokeLater(new Runnable() { public void run() { if (!processing) { try { processing = true; Throwable cause = ex instanceof OperationException ? ex.getCause() : ex; if (cause instanceof ResourceException) { ResourceException re = (ResourceException) cause; if (re.getStatus().equals(Status.CLIENT_ERROR_FORBIDDEN)) { // User is not allowed to do this operation JXDialog dialog = new JXDialog(frame, new JLabel(i18n .text(StreamflowResources.operation_not_permitted))); dialog.pack(); dialog.setLocationRelativeTo(frame); main.show(dialog); return; } else if (re.getStatus().equals(Status.CLIENT_ERROR_CONFLICT) || re.getStatus().equals(Status.CLIENT_ERROR_PRECONDITION_FAILED)) { //showErrorDialog(ex, frame, text(ErrorResources.concurrent_change)); if( showOptionDialog( ex, frame, text( ErrorResources.concurrent_change )) == 0 ) { main.callRefresh(); } return; } else if (re.getStatus().equals(Status.CLIENT_ERROR_UNAUTHORIZED)) { dialogs.showMessageDialog(frame, i18n.text(ErrorResources.unauthorized_access), "Info"); main.manageAccounts(); return; } else if (re.getStatus().equals(Status.CONNECTOR_ERROR_COMMUNICATION)) { showErrorDialog(ex, frame, text(ErrorResources.communication_error)); main.selectAccount(); return; } else if (re.getStatus().equals(Status.CLIENT_ERROR_UNPROCESSABLE_ENTITY ) ) { try { showErrorDialog(ex, frame, text( ErrorResources.valueOf( re.getStatus().getDescription() ) ) ); } catch ( Exception e ) { showErrorDialog(ex, frame, re.getMessage() + "\n" + re.getStatus().getUri(),re.getStatus().getDescription()); } return; } else { showErrorDialog(ex, frame, re.getMessage() + "\n" + re.getStatus().getUri()); return; } } try { String message = ex.getMessage(); if (message != null) { try { showErrorDialog(ex, frame, text( ErrorResources.valueOf( message ) ) ); } catch ( Exception e ) { message = HtmlErrorMessageExtractor.parse(ex.getMessage()); showErrorDialog(ex, frame, text(StreamflowResources.valueOf(HtmlErrorMessageExtractor.parse(ex.getMessage())))); } } else { // once again in case the resource enum does not exist showErrorDialog(ex, frame); } } catch (IllegalArgumentException iae) { // once again in case the resource enum does not exist - // now // showing non translated error msg showErrorDialog(ex, frame); } } finally { processing = false; } } } }); } private int showOptionDialog( Throwable ex, Frame frame, String text ) { Object[] options = {"OK"}; return JOptionPane.showOptionDialog( frame, text, text( ErrorResources.error ), JOptionPane.PLAIN_MESSAGE, JOptionPane.ERROR_MESSAGE, null, options, options[0] ); } private void showErrorDialog(Throwable ex, Frame frame, String errorMsg) { JXErrorPane pane = new JXErrorPane(); pane.setErrorInfo(new ErrorInfo(text(ErrorResources.error), errorMsg, null, text( ErrorResources.error ), ex, Level.SEVERE, Collections.<String, String> emptyMap())); pane.setPreferredSize(new Dimension(700, 400)); JXErrorPane.showDialog(frame, pane); } private void showErrorDialog(Throwable ex, Frame frame, String errorMsg, String detailedErrorMsg) { JXErrorPane pane = new JXErrorPane(); pane.setErrorInfo(new ErrorInfo(text(ErrorResources.error), errorMsg, detailedErrorMsg,text( ErrorResources.error ), ex, Level.SEVERE, Collections.<String, String> emptyMap())); pane.setPreferredSize(new Dimension(700, 400)); JXErrorPane.showDialog(frame, pane); } private void showErrorDialog(Throwable ex, Frame frame) { JXErrorPane pane = new JXErrorPane(); pane.setErrorInfo(new ErrorInfo(text(ErrorResources.error), ex.getMessage(), null, text( ErrorResources.error ), ex, Level.SEVERE, Collections.<String, String> emptyMap())); pane.setPreferredSize(new Dimension(700, 400)); JXErrorPane.showDialog(frame, pane); } private Throwable unwrap(Throwable e) { if (e instanceof OperationException) return e; if (e.getCause() != null) { if (e instanceof Error) { return unwrap(e.getCause()); } else if (e instanceof InvocationTargetException) { return unwrap(e.getCause()); } /* // removed since it is possible to have ResourceExceptions further down the cause hierarchy. else if (e instanceof ConstructionException) { return e; } */else return unwrap(e.getCause()); } return e; } }