Bug 573093: StackWalker and static methods to easily create Status
Change-Id: I711631db703fcc87ab37b8704a941b3c213f555b
Signed-off-by: Jonah Graham <jonah@kichwacoders.com>
Reviewed-on: https://git.eclipse.org/r/c/equinox/rt.equinox.bundles/+/179700
Tested-by: Thomas Watson <tjwatson@us.ibm.com>
Reviewed-by: Thomas Watson <tjwatson@us.ibm.com>
diff --git a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/StatusTest.java b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/StatusTest.java
index 692ade2..fe5a5aa 100644
--- a/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/StatusTest.java
+++ b/bundles/org.eclipse.equinox.common.tests/src/org/eclipse/equinox/common/tests/StatusTest.java
@@ -14,6 +14,8 @@
*******************************************************************************/
package org.eclipse.equinox.common.tests;
+import static org.junit.Assert.assertArrayEquals;
+
import java.io.File;
import java.io.IOException;
import java.net.URI;
@@ -234,4 +236,55 @@
}
+ public void testInfo() {
+ Status info = Status.info("message");
+ assertEquals(IStatus.INFO, info.getSeverity());
+ assertEquals("message", info.getMessage());
+ assertEquals(IStatus.OK, info.getCode());
+ assertEquals("org.eclipse.equinox.common.tests", info.getPlugin());
+ assertNull(info.getException());
+ assertArrayEquals(new IStatus[] {}, info.getChildren());
+ }
+
+ public void testWarning() {
+ Status warning = Status.warning("message");
+ assertEquals(IStatus.WARNING, warning.getSeverity());
+ assertEquals("message", warning.getMessage());
+ assertEquals(IStatus.OK, warning.getCode());
+ assertEquals("org.eclipse.equinox.common.tests", warning.getPlugin());
+ assertNull(warning.getException());
+ assertArrayEquals(new IStatus[] {}, warning.getChildren());
+ }
+
+ public void testWarningWithException() {
+
+ Status warningWithException = Status.warning("message", new Exception("exception"));
+ assertEquals(IStatus.WARNING, warningWithException.getSeverity());
+ assertEquals("message", warningWithException.getMessage());
+ assertEquals(IStatus.OK, warningWithException.getCode());
+ assertEquals("org.eclipse.equinox.common.tests", warningWithException.getPlugin());
+ assertEquals("exception", warningWithException.getException().getMessage());
+ assertArrayEquals(new IStatus[] {}, warningWithException.getChildren());
+ }
+
+ public void testError() {
+ Status error = Status.error("message");
+ assertEquals(IStatus.ERROR, error.getSeverity());
+ assertEquals("message", error.getMessage());
+ assertEquals(IStatus.OK, error.getCode());
+ assertEquals("org.eclipse.equinox.common.tests", error.getPlugin());
+ assertNull(error.getException());
+ assertArrayEquals(new IStatus[] {}, error.getChildren());
+ }
+
+ public void testErrorWithException() {
+ Status errorWithException = Status.error("message", new Exception("exception"));
+ assertEquals(IStatus.ERROR, errorWithException.getSeverity());
+ assertEquals("message", errorWithException.getMessage());
+ assertEquals(IStatus.OK, errorWithException.getCode());
+ assertEquals("org.eclipse.equinox.common.tests", errorWithException.getPlugin());
+ assertEquals("exception", errorWithException.getException().getMessage());
+ assertArrayEquals(new IStatus[] {}, errorWithException.getChildren());
+ }
+
}
diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/IStatus.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/IStatus.java
index f7124e1..d033aa2 100644
--- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/IStatus.java
+++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/IStatus.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2006 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -56,18 +56,23 @@
/** Status type severity (bit mask, value 1) indicating this status is informational only.
* @see #getSeverity()
* @see #matches(int)
+ * @see Status#info(String)
*/
public static final int INFO = 0x01;
/** Status type severity (bit mask, value 2) indicating this status represents a warning.
* @see #getSeverity()
* @see #matches(int)
+ * @see Status#warning(String)
+ * @see Status#warning(String, Throwable)
*/
public static final int WARNING = 0x02;
/** Status type severity (bit mask, value 4) indicating this status represents an error.
* @see #getSeverity()
* @see #matches(int)
+ * @see Status#error(String)
+ * @see Status#error(String, Throwable)
*/
public static final int ERROR = 0x04;
diff --git a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Status.java b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Status.java
index aad490f..54311fa 100644
--- a/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Status.java
+++ b/bundles/org.eclipse.equinox.common/src/org/eclipse/core/runtime/Status.java
@@ -1,5 +1,5 @@
/*******************************************************************************
- * Copyright (c) 2000, 2020 IBM Corporation and others.
+ * Copyright (c) 2000, 2021 IBM Corporation and others.
*
* This program and the accompanying materials
* are made available under the terms of the Eclipse Public License 2.0
@@ -24,6 +24,12 @@
* <p>
* This class can be used without OSGi running.
* </p>
+ * <p>
+ * For performance critical code, such as when {@link Status} objects are not created
+ * for logging or error handling, there may be a small performance penalty when using
+ * static methods or constructors that automatically determine the plug-in id from
+ * the provided {@link Class} or by using {@link StackWalker}.
+ * </p>
*/
public class Status implements IStatus {
@@ -76,6 +82,117 @@
*/
private static final IStatus[] theEmptyStatusArray = new IStatus[0];
+ private static StackWalker walker = StackWalker.getInstance(StackWalker.Option.RETAIN_CLASS_REFERENCE);
+
+ /**
+ * Construct a new status object with severity {@link IStatus#INFO},
+ * code {@link IStatus#OK}, and pluginId determined automatically
+ * from the calling class using {@link StackWalker}.
+ * The created status has no children.
+ *
+ * @param message a human-readable message, localized to the
+ * current locale
+ * @return the newly created status
+ * @since 3.15
+ */
+ public static Status info(String message) {
+ Class<?> callerClass = null;
+ try {
+ callerClass = walker.getCallerClass();
+ } catch (IllegalCallerException e) {
+ // ignored - use null class
+ }
+ return new Status(INFO, callerClass, OK, message, null);
+ }
+
+ /**
+ * Construct a new status object with severity {@link IStatus#WARNING},
+ * code {@link IStatus#OK}, and pluginId determined automatically
+ * from the calling class using {@link StackWalker}.
+ * The created status has no children.
+ *
+ * @param message a human-readable message, localized to the
+ * current locale
+ * @return the newly created status
+ * @since 3.15
+ */
+ public static Status warning(String message) {
+ Class<?> callerClass = null;
+ try {
+ callerClass = walker.getCallerClass();
+ } catch (IllegalCallerException e) {
+ // ignored - use null class
+ }
+ return new Status(WARNING, callerClass, OK, message, null);
+ }
+
+ /**
+ * Construct a new status object with severity {@link IStatus#WARNING},
+ * code {@link IStatus#OK}, and pluginId determined automatically
+ * from the calling class using {@link StackWalker}.
+ * The created status has no children.
+ *
+ * @param message a human-readable message, localized to the
+ * current locale
+ * @param exception a low-level exception, or <code>null</code> if not
+ * applicable
+ * @return the newly created status
+ * @since 3.15
+ */
+ public static Status warning(String message, Throwable exception) {
+ Class<?> callerClass = null;
+ try {
+ callerClass = walker.getCallerClass();
+ } catch (IllegalCallerException e) {
+ // ignored - use null class
+ }
+ return new Status(WARNING, callerClass, OK, message, exception);
+ }
+
+ /**
+ * Construct a new status object with severity {@link IStatus#ERROR},
+ * code {@link IStatus#OK}, and pluginId determined automatically
+ * from the calling class using {@link StackWalker}.
+ * The created status has no children.
+ *
+ * @param message a human-readable message, localized to the
+ * current locale
+ * @return the newly created status
+ * @since 3.15
+ */
+ public static Status error(String message) {
+ Class<?> callerClass = null;
+ try {
+ callerClass = walker.getCallerClass();
+ } catch (IllegalCallerException e) {
+ // ignored - use null class
+ }
+ return new Status(ERROR, callerClass, OK, message, null);
+ }
+
+ /**
+ * Construct a new status object with severity {@link IStatus#ERROR},
+ * code {@link IStatus#OK}, and pluginId determined automatically
+ * from the calling class using {@link StackWalker}.
+ * The created status has no children.
+ *
+ * @param message a human-readable message, localized to the
+ * current locale
+ * @param exception a low-level exception, or <code>null</code> if not
+ * applicable
+ * @return the newly created status
+ * @since 3.15
+ */
+ public static Status error(String message, Throwable exception) {
+ Class<?> callerClass = null;
+ try {
+ callerClass = walker.getCallerClass();
+ } catch (IllegalCallerException e) {
+ // ignored - use null class
+ }
+ return new Status(ERROR, callerClass, OK, message, exception);
+ }
+
/**
* Creates a new status object. The created status has no children.
*
@@ -208,7 +325,7 @@
* @param caller the relevant class to build unique identifier from
* @return identifier extracted for the given class
*/
- private String identifier(Class<?> caller) {
+ private static String identifier(Class<?> caller) {
return Optional.ofNullable(caller)//
.flatMap(c -> Optional.ofNullable(FrameworkUtil.getBundle(c)))//
.map(b -> b.getSymbolicName())//