| /*=============================================================================# |
| # Copyright (c) 2000, 2021 Stephan Wahlbrink and others. |
| # |
| # This program and the accompanying materials are made available under the |
| # terms of the Eclipse Public License 2.0 which is available at |
| # https://www.eclipse.org/legal/epl-2.0, or the Apache License, Version 2.0 |
| # which is available at https://www.apache.org/licenses/LICENSE-2.0. |
| # |
| # SPDX-License-Identifier: EPL-2.0 OR Apache-2.0 |
| # |
| # Contributors: |
| # Stephan Wahlbrink <sw@wahlbrink.eu> - initial API and implementation |
| #=============================================================================*/ |
| |
| package org.eclipse.statet.jcommons.status.eplatform; |
| |
| import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.ARRAY_CONTENTS; |
| import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.FIELD; |
| import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.PARAMETER; |
| import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.RETURN_TYPE; |
| import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.TYPE_ARGUMENT; |
| import static org.eclipse.statet.jcommons.lang.NullDefaultLocation.TYPE_BOUND; |
| |
| import org.eclipse.core.runtime.CoreException; |
| import org.eclipse.core.runtime.IProgressMonitor; |
| import org.eclipse.core.runtime.IProgressMonitorWithBlocking; |
| import org.eclipse.core.runtime.IStatus; |
| |
| import org.eclipse.statet.jcommons.collections.ImCollections; |
| import org.eclipse.statet.jcommons.lang.NonNull; |
| import org.eclipse.statet.jcommons.lang.NonNullByDefault; |
| import org.eclipse.statet.jcommons.lang.Nullable; |
| import org.eclipse.statet.jcommons.status.BasicProgressMonitor; |
| import org.eclipse.statet.jcommons.status.BasicProgressMonitor.ProgressData; |
| import org.eclipse.statet.jcommons.status.InfoStatus; |
| import org.eclipse.statet.jcommons.status.MultiStatus; |
| import org.eclipse.statet.jcommons.status.NullProgressMonitor; |
| import org.eclipse.statet.jcommons.status.ProgressMonitor; |
| import org.eclipse.statet.jcommons.status.Status; |
| import org.eclipse.statet.jcommons.status.StatusException; |
| |
| |
| /** |
| * A utility class to work with IStatus. |
| */ |
| @NonNullByDefault({ PARAMETER, RETURN_TYPE, FIELD, TYPE_BOUND, TYPE_ARGUMENT, ARRAY_CONTENTS }) |
| public class EStatusUtils { |
| |
| |
| private final static IStatus[] NO_ECHILDREN= new IStatus[0]; |
| |
| private static class EStatus implements IStatus { |
| |
| |
| private final Status status; |
| |
| |
| public EStatus(final Status status) { |
| this.status= status; |
| } |
| |
| |
| @Override |
| public int getSeverity() { |
| return this.status.getSeverity() & 0xFF; |
| } |
| |
| @Override |
| public boolean isOK() { |
| return (this.status.getSeverity() == Status.OK); |
| } |
| |
| @Override |
| public boolean matches(final int severityMask) { |
| return ((this.status.getSeverity() & severityMask) != 0); |
| } |
| |
| @Override |
| public String getPlugin() { |
| return this.status.getBundleId(); |
| } |
| |
| @Override |
| public int getCode() { |
| return this.status.getCode(); |
| } |
| |
| @Override |
| public String getMessage() { |
| return this.status.getMessage(); |
| } |
| |
| @Override |
| public @Nullable Throwable getException() { |
| return this.status.getException(); |
| } |
| |
| |
| @Override |
| public boolean isMultiStatus() { |
| return false; |
| } |
| |
| @Override |
| public IStatus[] getChildren() { |
| return NO_ECHILDREN; |
| } |
| |
| |
| @Override |
| public String toString() { |
| return this.status.toString(); |
| } |
| |
| } |
| |
| private static class EMultiStatus extends EStatus { |
| |
| |
| private final IStatus [] children; |
| |
| |
| public EMultiStatus(final Status status, final IStatus[] children) { |
| super(status); |
| this.children= children; |
| } |
| |
| |
| @Override |
| public boolean isMultiStatus() { |
| return true; |
| } |
| |
| @Override |
| public IStatus [] getChildren() { |
| return this.children; |
| } |
| |
| } |
| |
| |
| public static IStatus convert(final Status status) { |
| if (status.isMultiStatus()) { |
| final var children= status.getChildren(); |
| final var convertedChildren= new @NonNull IStatus[children.size()]; |
| for (int i= 0; i < convertedChildren.length; i++) { |
| convertedChildren[i]= convert(children.get(i)); |
| } |
| return new EMultiStatus(status, convertedChildren); |
| } |
| else { |
| if (status == Status.OK_STATUS) { |
| return org.eclipse.core.runtime.Status.OK_STATUS; |
| } |
| if (status == Status.CANCEL_STATUS) { |
| return org.eclipse.core.runtime.Status.CANCEL_STATUS; |
| } |
| return new EStatus(status); |
| } |
| } |
| |
| public static Status convert(final IStatus status) { |
| if (status.isMultiStatus()) { |
| final var children= status.getChildren(); |
| final var convertedChildren= new @NonNull Status[children.length]; |
| for (int i= 0; i < convertedChildren.length; i++) { |
| convertedChildren[i]= convert(children[i]); |
| } |
| return new MultiStatus(status.getPlugin(), status.getCode(), |
| status.getMessage(), status.getException(), |
| ImCollections.newList(convertedChildren) ); |
| } |
| else { |
| if (status == org.eclipse.core.runtime.Status.OK_STATUS) { |
| return Status.OK_STATUS; |
| } |
| if (status == org.eclipse.core.runtime.Status.CANCEL_STATUS) { |
| return Status.CANCEL_STATUS; |
| } |
| if (status instanceof EStatus) { |
| return ((EStatus) status).status; |
| } |
| return Status.newStatus(status.getSeverity(), |
| status.getPlugin(), status.getCode(), |
| status.getMessage(), status.getException() ); |
| } |
| } |
| |
| public static CoreException convert(final StatusException e) { |
| final CoreException convertedException= new CoreException(convert(e.getStatus())); |
| e.setStackTrace(e.getStackTrace()); |
| return convertedException; |
| } |
| |
| public static StatusException convert(final CoreException e) { |
| final StatusException convertedException= new StatusException(convert(e.getStatus())); |
| convertedException.setStackTrace(e.getStackTrace()); |
| return convertedException; |
| } |
| |
| |
| private static class EProgressData extends ProgressData { |
| |
| |
| private static final int TOTAL= 1 << 30; |
| |
| |
| private final IProgressMonitor monitor; |
| |
| private int workRemaining= TOTAL; |
| |
| |
| public EProgressData(final IProgressMonitor monitor) { |
| this.monitor= monitor; |
| } |
| |
| |
| @Override |
| public boolean isCanceled() { |
| return this.monitor.isCanceled(); |
| } |
| |
| @Override |
| protected void setCanceled(final boolean state) { |
| this.monitor.setCanceled(state); |
| } |
| |
| @Override |
| protected void onDataChanged(final byte data) { |
| switch (data) { |
| case MAIN_TASK_NAME: |
| this.monitor.subTask(""); //$NON-NLS-1$ |
| this.monitor.setTaskName(getMainTaskName()); |
| break; |
| case SUB_TASK_NAME: |
| this.monitor.subTask(getSubTaskName()); |
| break; |
| case PROGRESS_RATE: |
| if (this.workRemaining >= 0) { |
| final int workRemaining= (int) (getProgress() * TOTAL); |
| if (workRemaining < this.workRemaining) { |
| this.monitor.worked(this.workRemaining - workRemaining); |
| } |
| this.workRemaining= workRemaining; |
| } |
| break; |
| case BLOCKED: |
| { final Status blocked= getBlocked(); |
| if (blocked != null) { |
| this.monitor.setBlocked(EStatusUtils.convert(blocked)); |
| } |
| else { |
| this.monitor.clearBlocked(); |
| } |
| } |
| } |
| } |
| |
| } |
| |
| public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor, |
| final String name, final int totalWork, final int flags) { |
| if (eMonitor == null) { |
| return new NullProgressMonitor().newSubMonitor(flags); |
| } |
| |
| final EProgressData data= new EProgressData(eMonitor); |
| final BasicProgressMonitor convertedMonitor= new BasicProgressMonitor(data, flags); |
| if (totalWork > 0) { |
| eMonitor.beginTask(name, EProgressData.TOTAL); |
| convertedMonitor.beginTask(name, totalWork); |
| } |
| else { |
| eMonitor.beginTask(name, IProgressMonitor.UNKNOWN); |
| convertedMonitor.beginTask(name, ProgressMonitor.UNKNOWN); |
| data.workRemaining= -1; |
| } |
| return convertedMonitor; |
| } |
| |
| public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor, |
| final String name, final int totalWork) { |
| return convert(eMonitor, name, totalWork, ProgressMonitor.SUPPRESS_NONE); |
| } |
| |
| public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor, |
| final int totalWork) { |
| return convert(eMonitor, "", totalWork, ProgressMonitor.SUPPRESS_NONE); //$NON-NLS-1$ |
| } |
| |
| public static ProgressMonitor convert(final @Nullable IProgressMonitor eMonitor) { |
| return convert(eMonitor, "", 1, ProgressMonitor.SUPPRESS_NONE); //$NON-NLS-1$ |
| } |
| |
| public static ProgressMonitor convertChild(final @Nullable IProgressMonitor eMonitor) { |
| return convert(eMonitor, "", 1, ProgressMonitor.SUPPRESS_BEGINTASK_NAME); //$NON-NLS-1$ |
| } |
| |
| private static class EProgressMonitor implements IProgressMonitorWithBlocking { |
| |
| |
| private static final Status BLOCKED_NO_DETAIL= new InfoStatus("unknown", //$NON-NLS-1$ |
| "blocked" ); |
| |
| |
| private final ProgressMonitor m; |
| |
| private int workRemaining; |
| |
| public EProgressMonitor(final ProgressMonitor m) { |
| this.m= m; |
| } |
| |
| |
| @Override |
| public void beginTask(final String name, final int totalWork) { |
| this.workRemaining= totalWork; |
| this.m.beginTask(name, totalWork); |
| } |
| |
| @Override |
| public void setTaskName(final String name) { |
| this.m.beginTask(name, this.workRemaining); |
| } |
| |
| @Override |
| public void subTask(final String name) { |
| this.m.beginSubTask(name); |
| } |
| |
| @Override |
| public boolean isCanceled() { |
| return this.m.isCanceled(); |
| } |
| |
| @Override |
| public void setCanceled(final boolean value) { |
| this.m.setCanceled(value); |
| } |
| |
| @Override |
| public void worked(int work) { |
| if (this.workRemaining > 0 && work > 0) { |
| if (work > this.workRemaining) { |
| work= this.workRemaining; |
| } |
| this.workRemaining-= work; |
| this.m.addWorked(work); |
| } |
| } |
| |
| @Override |
| public void done() { |
| this.workRemaining= 0; |
| this.m.setWorkRemaining(0); |
| } |
| |
| @Override |
| public void internalWorked(final double work) { |
| } |
| |
| |
| @Override |
| public void setBlocked(final @Nullable IStatus reason) { |
| this.m.setBlocked((reason != null) ? convert(reason) : BLOCKED_NO_DETAIL); |
| } |
| |
| @Override |
| public void clearBlocked() { |
| this.m.clearBlocked(); |
| } |
| |
| } |
| |
| public static IProgressMonitor convert(final @Nullable ProgressMonitor m, |
| final String name, final int totalWork) { |
| if (m == null) { |
| return new org.eclipse.core.runtime.NullProgressMonitor(); |
| } |
| final EProgressMonitor convertedMonitor= new EProgressMonitor(m); |
| convertedMonitor.beginTask(name, totalWork); |
| return convertedMonitor; |
| } |
| |
| public static IProgressMonitor convert(final @Nullable ProgressMonitor m, |
| final int totalWork) { |
| return convert(m, "", totalWork); //$NON-NLS-1$ |
| } |
| |
| public static IProgressMonitor convert(final @Nullable ProgressMonitor m) { |
| if (m == null) { |
| return new org.eclipse.core.runtime.NullProgressMonitor(); |
| } |
| return new EProgressMonitor(m); |
| } |
| |
| } |