/* * Copyright 2000-2015 JetBrains s.r.o. * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package com.jetbrains.lang.dart.ide.refactoring.status; import com.google.common.collect.Lists; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; import java.util.List; /** * Outcome of a condition checking operation. */ public class RefactoringStatus { @NotNull private final List<RefactoringStatusEntry> entries = Lists.newArrayList(); @NotNull private RefactoringStatusSeverity severity = RefactoringStatusSeverity.OK; /** * Adds given {@link RefactoringStatusEntry} and updates {@link #severity}. */ public void addEntry(@NotNull RefactoringStatusEntry entry) { entries.add(entry); severity = max(severity, entry.getSeverity()); } /** * Adds a <code>ERROR</code> entry filled with the given message to this status. */ public void addError(@NotNull String msg) { addError(msg, null); } /** * Adds a <code>ERROR</code> entry filled with the given message and status to this status. */ public void addError(@NotNull String msg, @Nullable RefactoringStatusContext context) { addEntry(new RefactoringStatusEntry(RefactoringStatusSeverity.ERROR, msg, context)); } /** * Adds a <code>FATAL</code> entry filled with the given message to this status. */ public void addFatalError(@NotNull String msg) { addFatalError(msg, null); } /** * Adds a <code>FATAL</code> entry filled with the given message and status to this status. */ public void addFatalError(@NotNull String msg, @Nullable RefactoringStatusContext context) { addEntry(new RefactoringStatusEntry(RefactoringStatusSeverity.FATAL, msg, context)); } /** * Adds a <code>WARNING</code> entry filled with the given message to this status. */ public void addWarning(String msg) { addWarning(msg, null); } /** * Adds a <code>WARNING</code> entry filled with the given message and status to this status. */ public void addWarning(@NotNull String msg, @Nullable RefactoringStatusContext context) { addEntry(new RefactoringStatusEntry(RefactoringStatusSeverity.WARNING, msg, context)); } /** * @return the copy of this {@link RefactoringStatus} with {@link RefactoringStatusSeverity#ERROR} * replaced with {@link RefactoringStatusSeverity#FATAL}. */ @NotNull public RefactoringStatus escalateErrorToFatal() { RefactoringStatus result = new RefactoringStatus(); for (RefactoringStatusEntry entry : entries) { RefactoringStatusSeverity severity = entry.getSeverity(); if (severity == RefactoringStatusSeverity.ERROR) { severity = RefactoringStatusSeverity.FATAL; } result.addEntry(new RefactoringStatusEntry(severity, entry.getMessage(), entry.getContext())); } return result; } /** * @return the {@link RefactoringStatusEntry}s. */ @NotNull public List<RefactoringStatusEntry> getEntries() { return entries; } /** * @return the RefactoringStatusEntry with the highest severity, or <code>null</code> if no * entries are present. */ @Nullable public RefactoringStatusEntry getEntryWithHighestSeverity() { if (entries.isEmpty()) { return null; } RefactoringStatusEntry result = entries.get(0); for (RefactoringStatusEntry entry : entries) { if (result.getSeverity().ordinal() < entry.getSeverity().ordinal()) { result = entry; } } return result; } /** * Return the message from the {@link RefactoringStatusEntry} with the highest severity; may be * <code>null</code> if not entries are present. */ @Nullable public String getMessage() { RefactoringStatusEntry entry = getEntryWithHighestSeverity(); if (entry == null) { return null; } return entry.getMessage(); } /** * @return the current severity of the {@link RefactoringStatus}. */ @NotNull public RefactoringStatusSeverity getSeverity() { return severity; } /** * @return <code>true</code> if the current severity is <code> * FATAL</code> or <code>ERROR</code>. */ public boolean hasError() { return severity == RefactoringStatusSeverity.FATAL || severity == RefactoringStatusSeverity.ERROR; } /** * @return <code>true</code> if the current severity is <code>FATAL</code>. */ public boolean hasFatalError() { return severity == RefactoringStatusSeverity.FATAL; } /** * @return <code>true</code> if the current severity is <code> * FATAL</code>, <code>ERROR</code>, <code>WARNING</code> or <code>INFO</code>. */ public boolean hasInfo() { return severity == RefactoringStatusSeverity.FATAL || severity == RefactoringStatusSeverity.ERROR || severity == RefactoringStatusSeverity.WARNING || severity == RefactoringStatusSeverity.INFO; } /** * @return <code>true</code> if the current severity is <code> * FATAL</code>, <code>ERROR</code> or <code>WARNING</code>. */ public boolean hasWarning() { return severity == RefactoringStatusSeverity.FATAL || severity == RefactoringStatusSeverity.ERROR || severity == RefactoringStatusSeverity.WARNING; } /** * @return <code>true</code> if the severity is <code>OK</code>. */ public boolean isOK() { return severity == RefactoringStatusSeverity.OK; } /** * Merges the receiver and the parameter statuses. The resulting list of entries in the receiver * will contain entries from both. The resulting severity in the receiver will be the more severe * of its current severity and the parameter's severity. Merging with <code>null</code> is allowed * - it has no effect. */ public void merge(@Nullable RefactoringStatus other) { if (other == null) { return; } entries.addAll(other.entries); severity = max(severity, other.getSeverity()); } @Override public String toString() { StringBuilder sb = new StringBuilder(); sb.append("<").append(severity.name()); if (!isOK()) { sb.append("\n"); for (RefactoringStatusEntry entry : entries) { sb.append("\t").append(entry).append("\n"); } } sb.append(">"); return sb.toString(); } /** * @return the new {@link RefactoringStatus} with {@link RefactoringStatusSeverity#ERROR}. */ @NotNull public static RefactoringStatus createErrorStatus(String msg) { RefactoringStatus status = new RefactoringStatus(); status.addError(msg); return status; } /** * @return the new {@link RefactoringStatus} with {@link RefactoringStatusSeverity#FATAL}. */ @NotNull public static RefactoringStatus createFatalErrorStatus(String msg) { RefactoringStatus status = new RefactoringStatus(); status.addFatalError(msg); return status; } /** * @return the new {@link RefactoringStatus} with {@link RefactoringStatusSeverity#FATAL}. */ @NotNull public static RefactoringStatus createFatalErrorStatus(String msg, RefactoringStatusContext context) { RefactoringStatus status = new RefactoringStatus(); status.addFatalError(msg, context); return status; } /** * @return the new {@link RefactoringStatus} with {@link RefactoringStatusSeverity#WARNING}. */ @NotNull public static RefactoringStatus createWarningStatus(String msg) { RefactoringStatus status = new RefactoringStatus(); status.addWarning(msg); return status; } /** * @return the {@link Enum} value with maximal ordinal. */ @NotNull private static <T extends Enum<T>> T max(@NotNull T a, @NotNull T b) { if (b.ordinal() > a.ordinal()) { return b; } return a; } }