1 /******************************************************************************* 2 * Copyright (c) 2000, 2020 IBM Corporation and others. 3 * 4 * This program and the accompanying materials 5 * are made available under the terms of the Eclipse Public License 2.0 6 * which accompanies this distribution, and is available at 7 * https://www.eclipse.org/legal/epl-2.0/ 8 * 9 * SPDX-License-Identifier: EPL-2.0 10 * 11 * Contributors: 12 * IBM Corporation - initial API and implementation 13 * Alexander Fedorov (ArSysOp) - Bug 561712 14 *******************************************************************************/ 15 package org.eclipse.core.runtime; 16 17 import java.util.Optional; 18 import org.eclipse.core.internal.runtime.LocalizationUtils; 19 import org.osgi.framework.FrameworkUtil; 20 21 /** 22 * A concrete status implementation, suitable either for 23 * instantiating or subclassing. 24 * <p> 25 * This class can be used without OSGi running. 26 * </p> 27 */ 28 public class Status implements IStatus { 29 30 /** 31 * Constant used to indicate an unknown plugin id. 32 */ 33 private static final String unknownId = "unknown"; //$NON-NLS-1$ 34 35 /** 36 * A standard OK status with an "ok" message. 37 * 38 * @since 3.0 39 */ 40 public static final IStatus OK_STATUS = new Status(OK, unknownId, OK, LocalizationUtils.safeLocalize("ok"), null); //$NON-NLS-1$ 41 /** 42 * A standard CANCEL status with no message. 43 * 44 * @since 3.0 45 */ 46 public static final IStatus CANCEL_STATUS = new Status(CANCEL, unknownId, 1, "", null); //$NON-NLS-1$ 47 /** 48 * The severity. One of 49 * <ul> 50 * <li><code>CANCEL</code></li> 51 * <li><code>ERROR</code></li> 52 * <li><code>WARNING</code></li> 53 * <li><code>INFO</code></li> 54 * <li>or <code>OK</code> (0)</li> 55 * </ul> 56 */ 57 private int severity = OK; 58 59 /** Unique identifier of plug-in. 60 */ 61 private String pluginId; 62 63 /** Plug-in-specific status code. 64 */ 65 private int code; 66 67 /** Message, localized to the current locale. 68 */ 69 private String message; 70 71 /** Wrapped exception, or <code>null</code> if none. 72 */ 73 private Throwable exception = null; 74 75 /** Constant to avoid generating garbage. 76 */ 77 private static final IStatus[] theEmptyStatusArray = new IStatus[0]; 78 79 /** 80 * Creates a new status object. The created status has no children. 81 * 82 * @param severity the severity; one of <code>OK</code>, <code>ERROR</code>, 83 * <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code> 84 * @param caller the relevant class to build unique identifier from 85 * @param code the caller-specific status code, or <code>OK</code> 86 * @param message a human-readable message, localized to the 87 * current locale 88 * @param exception a low-level exception, or <code>null</code> if not 89 * applicable 90 * 91 * @since 3.12 92 */ Status(int severity, Class<?> caller, int code, String message, Throwable exception)93 public Status(int severity, Class<?> caller, int code, String message, Throwable exception) { 94 setSeverity(severity); 95 setPlugin(identifier(caller)); 96 setCode(code); 97 setMessage(message); 98 setException(exception); 99 } 100 101 /** 102 * Creates a new status object. The created status has no children. 103 * 104 * @param severity the severity; one of <code>OK</code>, <code>ERROR</code>, 105 * <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code> 106 * @param pluginId the unique identifier of the relevant plug-in 107 * @param code the plug-in-specific status code, or <code>OK</code> 108 * @param message a human-readable message, localized to the 109 * current locale 110 * @param exception a low-level exception, or <code>null</code> if not 111 * applicable 112 */ Status(int severity, String pluginId, int code, String message, Throwable exception)113 public Status(int severity, String pluginId, int code, String message, Throwable exception) { 114 setSeverity(severity); 115 setPlugin(pluginId); 116 setCode(code); 117 setMessage(message); 118 setException(exception); 119 } 120 121 /** 122 * Simplified constructor of a new status object; assumes that code is <code>OK</code>. 123 * The created status has no children. 124 * 125 * @param severity the severity; one of <code>OK</code>, <code>ERROR</code>, 126 * <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code> 127 * @param caller the relevant class to build unique identifier from 128 * @param message a human-readable message, localized to the 129 * current locale 130 * @param exception a low-level exception, or <code>null</code> if not 131 * applicable 132 * 133 * @since 3.12 134 */ Status(int severity, Class<?> caller, String message, Throwable exception)135 public Status(int severity, Class<?> caller, String message, Throwable exception) { 136 setSeverity(severity); 137 setPlugin(identifier(caller)); 138 setMessage(message); 139 setException(exception); 140 setCode(OK); 141 } 142 143 /** 144 * Simplified constructor of a new status object; assumes that code is <code>OK</code>. 145 * The created status has no children. 146 * 147 * @param severity the severity; one of <code>OK</code>, <code>ERROR</code>, 148 * <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code> 149 * @param pluginId the unique identifier of the relevant plug-in 150 * @param message a human-readable message, localized to the 151 * current locale 152 * @param exception a low-level exception, or <code>null</code> if not 153 * applicable 154 * 155 * @since org.eclipse.equinox.common 3.3 156 */ Status(int severity, String pluginId, String message, Throwable exception)157 public Status(int severity, String pluginId, String message, Throwable exception) { 158 setSeverity(severity); 159 setPlugin(pluginId); 160 setMessage(message); 161 setException(exception); 162 setCode(OK); 163 } 164 165 /** 166 * Simplified constructor of a new status object; assumes that code is <code>OK</code> and 167 * exception is <code>null</code>. The created status has no children. 168 * 169 * @param severity the severity; one of <code>OK</code>, <code>ERROR</code>, 170 * <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code> 171 * @param caller the relevant class to build unique identifier from 172 * @param message a human-readable message, localized to the 173 * current locale 174 * 175 * @since 3.12 176 */ Status(int severity, Class<?> caller, String message)177 public Status(int severity, Class<?> caller, String message) { 178 setSeverity(severity); 179 setPlugin(identifier(caller)); 180 setMessage(message); 181 setCode(OK); 182 setException(null); 183 } 184 185 /** 186 * Simplified constructor of a new status object; assumes that code is <code>OK</code> and 187 * exception is <code>null</code>. The created status has no children. 188 * 189 * @param severity the severity; one of <code>OK</code>, <code>ERROR</code>, 190 * <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code> 191 * @param pluginId the unique identifier of the relevant plug-in 192 * @param message a human-readable message, localized to the 193 * current locale 194 * 195 * @since org.eclipse.equinox.common 3.3 196 */ Status(int severity, String pluginId, String message)197 public Status(int severity, String pluginId, String message) { 198 setSeverity(severity); 199 setPlugin(pluginId); 200 setMessage(message); 201 setCode(OK); 202 setException(null); 203 } 204 205 /** 206 * Extracts an identifier from the given class: either bundle symbolic name or class name, never returns <code>null</code> 207 * 208 * @param caller the relevant class to build unique identifier from 209 * @return identifier extracted for the given class 210 */ identifier(Class<?> caller)211 private String identifier(Class<?> caller) { 212 return Optional.ofNullable(caller)// 213 .flatMap(c -> Optional.ofNullable(FrameworkUtil.getBundle(c)))// 214 .map(b -> b.getSymbolicName())// 215 .orElseGet(() -> Optional.ofNullable(caller)// 216 .map(c -> c.getName())// 217 .orElse(getClass().getName())); 218 } 219 220 @Override getChildren()221 public IStatus[] getChildren() { 222 return theEmptyStatusArray; 223 } 224 225 @Override getCode()226 public int getCode() { 227 return code; 228 } 229 230 @Override getException()231 public Throwable getException() { 232 return exception; 233 } 234 235 @Override getMessage()236 public String getMessage() { 237 return message; 238 } 239 240 @Override getPlugin()241 public String getPlugin() { 242 return pluginId; 243 } 244 245 @Override getSeverity()246 public int getSeverity() { 247 return severity; 248 } 249 250 @Override isMultiStatus()251 public boolean isMultiStatus() { 252 return false; 253 } 254 255 @Override isOK()256 public boolean isOK() { 257 return severity == OK; 258 } 259 260 @Override matches(int severityMask)261 public boolean matches(int severityMask) { 262 return (severity & severityMask) != 0; 263 } 264 265 /** 266 * Sets the status code. 267 * 268 * @param code the plug-in-specific status code, or <code>OK</code> 269 */ setCode(int code)270 protected void setCode(int code) { 271 this.code = code; 272 } 273 274 /** 275 * Sets the exception. 276 * 277 * @param exception a low-level exception, or <code>null</code> if not 278 * applicable 279 */ setException(Throwable exception)280 protected void setException(Throwable exception) { 281 this.exception = exception; 282 } 283 284 /** 285 * Sets the message. If null is passed, message is set to an empty 286 * string. 287 * 288 * @param message a human-readable message, localized to the 289 * current locale 290 */ setMessage(String message)291 protected void setMessage(String message) { 292 if (message == null) 293 this.message = ""; //$NON-NLS-1$ 294 else 295 this.message = message; 296 } 297 298 /** 299 * Sets the plug-in id. 300 * 301 * @param pluginId the unique identifier of the relevant plug-in 302 */ setPlugin(String pluginId)303 protected void setPlugin(String pluginId) { 304 Assert.isLegal(pluginId != null && pluginId.length() > 0); 305 this.pluginId = pluginId; 306 } 307 308 /** 309 * Sets the severity. 310 * 311 * @param severity the severity; one of <code>OK</code>, <code>ERROR</code>, 312 * <code>INFO</code>, <code>WARNING</code>, or <code>CANCEL</code> 313 */ setSeverity(int severity)314 protected void setSeverity(int severity) { 315 Assert.isLegal(severity == OK || severity == ERROR || severity == WARNING || severity == INFO || severity == CANCEL); 316 this.severity = severity; 317 } 318 319 /** 320 * Returns a string representation of the status, suitable 321 * for debugging purposes only. 322 */ 323 @Override toString()324 public String toString() { 325 StringBuilder buf = new StringBuilder(); 326 buf.append("Status "); //$NON-NLS-1$ 327 if (severity == OK) { 328 buf.append("OK"); //$NON-NLS-1$ 329 } else if (severity == ERROR) { 330 buf.append("ERROR"); //$NON-NLS-1$ 331 } else if (severity == WARNING) { 332 buf.append("WARNING"); //$NON-NLS-1$ 333 } else if (severity == INFO) { 334 buf.append("INFO"); //$NON-NLS-1$ 335 } else if (severity == CANCEL) { 336 buf.append("CANCEL"); //$NON-NLS-1$ 337 } else { 338 buf.append("severity="); //$NON-NLS-1$ 339 buf.append(severity); 340 } 341 buf.append(": "); //$NON-NLS-1$ 342 buf.append(pluginId); 343 buf.append(" code="); //$NON-NLS-1$ 344 buf.append(code); 345 buf.append(' '); 346 buf.append(message); 347 buf.append(' '); 348 buf.append(exception); 349 return buf.toString(); 350 } 351 } 352