001: /*
002: * Copyright (c) 2004-2006, Jean-François Brazeau. All rights reserved.
003: *
004: * Redistribution and use in source and binary forms, with or without
005: * modification, are permitted provided that the following conditions are met:
006: *
007: * 1. Redistributions of source code must retain the above copyright notice,
008: * this list of conditions and the following disclaimer.
009: *
010: * 2. Redistributions in binary form must reproduce the above copyright
011: * notice, this list of conditions and the following disclaimer in the
012: * documentation and/or other materials provided with the distribution.
013: *
014: * 3. The name of the author may not be used to endorse or promote products
015: * derived from this software without specific prior written permission.
016: *
017: * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
018: * IMPLIEDWARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
019: * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
020: * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
021: * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
022: * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
023: * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND
024: * ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR
025: * TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
026: * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
027: */
028: package jfb.tools.activitymgr.ui.util;
029:
030: import jfb.tools.activitymgr.AbstractException;
031: import jfb.tools.activitymgr.ui.dialogs.ErrorDialog;
032:
033: import org.apache.log4j.Logger;
034: import org.eclipse.swt.custom.BusyIndicator;
035: import org.eclipse.swt.widgets.Shell;
036:
037: /**
038: * Offre un contexte d'exécution sécurisé.
039: *
040: * <p>Si une exception est levée dans le traitement, elle est attrapée
041: * et un popup d'erreur est affiché.</p>
042: *
043: * <p>Exemple d'utilisation :<br>
044: * <pre>
045: * // Initialisation du contexte d'exécution sécurisé
046: * SafeRunner safeRunner = new SafeRunner() {
047: * public Object runUnsafe() throws Exception {
048: * // Declare unsafe code...
049: * return result;
050: * }
051: * };
052: * // Exécution du traitement
053: * Object result = safeRunner.run(parent.getShell(), "");
054: * </pre>
055: */
056: public abstract class SafeRunner {
057:
058: /** Logger */
059: private static Logger log = Logger.getLogger(SafeRunner.class);
060:
061: /**
062: * Classe permettant de stoker le résultat du traitement.
063: * (sans cet objet il n'est pas possible de récupérer le résultat
064: * dans le traitement exécuté dans le Runnable puisqu'il faut
065: * passer par une référence finale).
066: */
067: private static class Result {
068: public Object value;
069: }
070:
071: /**
072: * Lance le traitement dans le contexte sécurisé.
073: * @param parentShell shell parent (peut être nul).
074: * @return le résultat du traitement.
075: */
076: public Object run(Shell parentShell) {
077: return run(parentShell, null);
078: }
079:
080: /**
081: * Lance le traitement dans le contexte sécurisé.
082: * @param parentShell shell parent (peut être nul).
083: * @param defaultValue la valeur à retourner par défaut.
084: * @return le résultat du traitement.
085: */
086: // TODO Supprimer ce bout de code si il n'y a pas de pb
087: // public Object run(Shell parentShell, Object defaultValue) {
088: // log.debug("ParentShell : " + parentShell);
089: // Object result = defaultValue;
090: // // Changement du curseur
091: // Cursor waitCursor = parentShell.getDisplay().getSystemCursor(SWT.CURSOR_WAIT);
092: // parentShell.setCursor(waitCursor);
093: // // Exécution du traitement
094: // try { result = runUnsafe(); }
095: // catch (AbstractException e) {
096: // log.info("UI Exception", e);
097: // Shell parent = Display.getCurrent().getActiveShell();
098: // new ErrorDialog(parent, "Unable to complete operation : '" + e.getMessage() + "'", e).open();
099: // }
100: // catch (Throwable t) {
101: // log.error("Unexpected error", t);
102: // Shell parent = Display.getCurrent().getActiveShell();
103: // new ErrorDialog(parent, "Unexpected error", t).open();
104: // }
105: // finally {
106: // // Retour du curseur normal
107: // Cursor normalCursor = parentShell.getDisplay().getSystemCursor(SWT.CURSOR_ARROW);
108: // parentShell.setCursor(normalCursor);
109: // }
110: // // Retour du résultat
111: // log.debug(" -> result='" + result + "'");
112: // return result;
113: // }
114: public Object run(final Shell parentShell, Object defaultValue) {
115: log.debug("ParentShell : " + parentShell);
116: final Result result = new Result();
117: result.value = defaultValue;
118: // Exécution du traitement
119: BusyIndicator.showWhile(parentShell.getDisplay(),
120: new Runnable() {
121: public void run() {
122: try {
123: result.value = runUnsafe();
124: } catch (AbstractException e) {
125: log.info("UI Exception", e);
126: new ErrorDialog(parentShell,
127: "Unable to complete operation : '"
128: + e.getMessage() + "'", e)
129: .open();
130: } catch (Throwable t) {
131: log.error("Unexpected error", t);
132: new ErrorDialog(parentShell,
133: "Unexpected error", t).open();
134: }
135: }
136: });
137: // Retour du résultat
138: log.debug(" -> result='" + result.value + "'");
139: return result.value;
140: }
141:
142: /**
143: * Traitement potentiellement à risque.
144: *
145: * <p>Cette méthode doit être implémentée.</p>
146: *
147: * @return le résultat du traitement.
148: * @throws Exception le traitement peut potentiellement lever n'importe
149: * quelle exception.
150: */
151: protected abstract Object runUnsafe() throws Exception;
152:
153: }
|