001: /*******************************************************************************
002: * Copyright (c) 2000, 2007 IBM Corporation and others.
003: * All rights reserved. This program and the accompanying materials
004: * are made available under the terms of the Eclipse Public License v1.0
005: * which accompanies this distribution, and is available at
006: * http://www.eclipse.org/legal/epl-v10.html
007: *
008: * Contributors:
009: * IBM Corporation - initial API and implementation
010: *******************************************************************************/package org.eclipse.ui.internal.misc;
011:
012: import java.lang.reflect.InvocationTargetException;
013: import java.lang.reflect.Method;
014: import java.util.ArrayList;
015: import java.util.Iterator;
016: import java.util.List;
017:
018: import org.eclipse.core.runtime.Assert;
019: import org.eclipse.core.runtime.CoreException;
020: import org.eclipse.core.runtime.IStatus;
021: import org.eclipse.core.runtime.MultiStatus;
022: import org.eclipse.core.runtime.Status;
023: import org.eclipse.swt.widgets.Shell;
024: import org.eclipse.ui.internal.WorkbenchMessages;
025: import org.eclipse.ui.internal.WorkbenchPlugin;
026: import org.eclipse.ui.statushandlers.StatusManager;
027:
028: /**
029: * Utility class to create status objects.
030: *
031: * @private - This class is an internal implementation class and should
032: * not be referenced or subclassed outside of the workbench
033: */
034: public class StatusUtil {
035: /**
036: * Answer a flat collection of the passed status and its recursive children
037: */
038: protected static List flatten(IStatus aStatus) {
039: List result = new ArrayList();
040:
041: if (aStatus.isMultiStatus()) {
042: IStatus[] children = aStatus.getChildren();
043: for (int i = 0; i < children.length; i++) {
044: IStatus currentChild = children[i];
045: if (currentChild.isMultiStatus()) {
046: Iterator childStatiiEnum = flatten(currentChild)
047: .iterator();
048: while (childStatiiEnum.hasNext()) {
049: result.add(childStatiiEnum.next());
050: }
051: } else {
052: result.add(currentChild);
053: }
054: }
055: } else {
056: result.add(aStatus);
057: }
058:
059: return result;
060: }
061:
062: /**
063: * This method must not be called outside the workbench.
064: *
065: * Utility method for creating status.
066: */
067: protected static IStatus newStatus(IStatus[] stati, String message,
068: Throwable exception) {
069:
070: Assert.isTrue(message != null);
071: Assert.isTrue(message.trim().length() != 0);
072:
073: return new MultiStatus(WorkbenchPlugin.PI_WORKBENCH,
074: IStatus.ERROR, stati, message, exception);
075: }
076:
077: public static IStatus newStatus(String pluginId, Throwable exception) {
078: return newStatus(pluginId, getLocalizedMessage(exception),
079: exception);
080: }
081:
082: /**
083: * Returns a localized message describing the given exception. If the given exception does not
084: * have a localized message, this returns the string "An error occurred".
085: *
086: * @param exception
087: * @return
088: */
089: public static String getLocalizedMessage(Throwable exception) {
090: String message = exception.getLocalizedMessage();
091:
092: if (message != null) {
093: return message;
094: }
095:
096: // Workaround for the fact that CoreException does not implement a getLocalizedMessage() method.
097: // Remove this branch when and if CoreException implements getLocalizedMessage()
098: if (exception instanceof CoreException) {
099: CoreException ce = (CoreException) exception;
100: return ce.getStatus().getMessage();
101: }
102:
103: return WorkbenchMessages.StatusUtil_errorOccurred;
104: }
105:
106: /**
107: * Creates a new Status based on the original status, but with a different message
108: *
109: * @param originalStatus
110: * @param newMessage
111: * @return
112: */
113: public static IStatus newStatus(IStatus originalStatus,
114: String newMessage) {
115: return new Status(originalStatus.getSeverity(), originalStatus
116: .getPlugin(), originalStatus.getCode(), newMessage,
117: originalStatus.getException());
118: }
119:
120: public static IStatus newStatus(String pluginId, String message,
121: Throwable exception) {
122: return new Status(IStatus.ERROR, pluginId, IStatus.OK, message,
123: getCause(exception));
124: }
125:
126: public static Throwable getCause(Throwable exception) {
127: // Figure out which exception should actually be logged -- if the given exception is
128: // a wrapper, unwrap it
129: Throwable cause = null;
130: if (exception != null) {
131: if (exception instanceof CoreException) {
132: // Workaround: CoreException contains a cause, but does not actually implement getCause().
133: // If we get a CoreException, we need to manually unpack the cause. Otherwise, use
134: // the general-purpose mechanism. Remove this branch if CoreException ever implements
135: // a correct getCause() method.
136: CoreException ce = (CoreException) exception;
137: cause = ce.getStatus().getException();
138: } else {
139: // use reflect instead of a direct call to getCause(), to allow compilation against JCL Foundation (bug 80053)
140: try {
141: Method causeMethod = exception.getClass()
142: .getMethod("getCause", new Class[0]); //$NON-NLS-1$
143: Object o = causeMethod.invoke(exception,
144: new Object[0]);
145: if (o instanceof Throwable) {
146: cause = (Throwable) o;
147: }
148: } catch (NoSuchMethodException e) {
149: // ignore
150: } catch (IllegalArgumentException e) {
151: // ignore
152: } catch (IllegalAccessException e) {
153: // ignore
154: } catch (InvocationTargetException e) {
155: // ignore
156: }
157: }
158:
159: if (cause == null) {
160: cause = exception;
161: }
162: }
163:
164: return cause;
165: }
166:
167: /**
168: * This method must not be called outside the workbench.
169: *
170: * Utility method for creating status.
171: */
172: public static IStatus newStatus(int severity, String message,
173: Throwable exception) {
174:
175: String statusMessage = message;
176: if (message == null || message.trim().length() == 0) {
177: if (exception.getMessage() == null) {
178: statusMessage = exception.toString();
179: } else {
180: statusMessage = exception.getMessage();
181: }
182: }
183:
184: return new Status(severity, WorkbenchPlugin.PI_WORKBENCH,
185: severity, statusMessage, getCause(exception));
186: }
187:
188: /**
189: * This method must not be called outside the workbench.
190: *
191: * Utility method for creating status.
192: */
193: public static IStatus newStatus(List children, String message,
194: Throwable exception) {
195:
196: List flatStatusCollection = new ArrayList();
197: Iterator iter = children.iterator();
198: while (iter.hasNext()) {
199: IStatus currentStatus = (IStatus) iter.next();
200: Iterator childrenIter = flatten(currentStatus).iterator();
201: while (childrenIter.hasNext()) {
202: flatStatusCollection.add(childrenIter.next());
203: }
204: }
205:
206: IStatus[] stati = new IStatus[flatStatusCollection.size()];
207: flatStatusCollection.toArray(stati);
208: return newStatus(stati, message, exception);
209: }
210:
211: /**
212: * This method must not be called outside the workbench.
213: *
214: * Utility method for handling status.
215: */
216: public static void handleStatus(IStatus status, int hint,
217: Shell shell) {
218: StatusManager.getManager().handle(status, hint);
219: }
220:
221: /**
222: * This method must not be called outside the workbench.
223: *
224: * Utility method for handling status.
225: */
226: public static void handleStatus(Throwable e, int hint) {
227: StatusManager.getManager().handle(
228: newStatus(WorkbenchPlugin.PI_WORKBENCH, e), hint);
229: }
230:
231: /**
232: * This method must not be called outside the workbench.
233: *
234: * Utility method for handling status.
235: */
236: public static void handleStatus(String message, Throwable e,
237: int hint) {
238: StatusManager.getManager().handle(
239: newStatus(WorkbenchPlugin.PI_WORKBENCH, message, e),
240: hint);
241: }
242:
243: /**
244: * This method must not be called outside the workbench.
245: *
246: * Utility method for handling status.
247: */
248: public static void handleStatus(String message, Throwable e,
249: int hint, Shell shell) {
250: StatusManager.getManager().handle(
251: newStatus(WorkbenchPlugin.PI_WORKBENCH, message, e),
252: hint);
253: }
254:
255: /**
256: * This method must not be called outside the workbench.
257: *
258: * Utility method for handling status.
259: */
260: public static void handleStatus(IStatus status, String message,
261: int hint) {
262: StatusManager.getManager().handle(newStatus(status, message),
263: hint);
264: }
265:
266: /**
267: * This method must not be called outside the workbench.
268: *
269: * Utility method for handling status.
270: */
271: public static void handleStatus(IStatus status, String message,
272: int hint, Shell shell) {
273: StatusManager.getManager().handle(newStatus(status, message),
274: hint);
275: }
276:
277: /**
278: * This method must not be called outside the workbench.
279: *
280: * Utility method for handling status.
281: */
282: public static void handleStatus(String message, int hint) {
283: handleStatus(message, null, hint);
284: }
285:
286: /**
287: * This method must not be called outside the workbench.
288: *
289: * Utility method for handling status.
290: */
291: public static void handleStatus(String message, int hint,
292: Shell shell) {
293: handleStatus(message, null, hint);
294: }
295: }
|