diff --git a/core/src/main/java/hudson/util/FormFillFailure.java b/core/src/main/java/hudson/util/FormFillFailure.java new file mode 100644 index 0000000000000000000000000000000000000000..d1cec23b42a9ece407d2eee7f5cbe034fbb818f2 --- /dev/null +++ b/core/src/main/java/hudson/util/FormFillFailure.java @@ -0,0 +1,212 @@ +/* + * The MIT License + * + * Copyright (c) 2004-2017, Sun Microsystems, Inc., CloudBees, Inc. + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + */ +package hudson.util; + +import hudson.Functions; +import hudson.Util; +import java.io.IOException; +import java.util.Locale; +import javax.annotation.Nonnull; +import javax.servlet.ServletException; +import javax.servlet.http.HttpServletResponse; +import jenkins.model.Jenkins; +import org.kohsuke.stapler.HttpResponse; +import org.kohsuke.stapler.Stapler; +import org.kohsuke.stapler.StaplerRequest; +import org.kohsuke.stapler.StaplerResponse; + +/** + * Represents a failure in a form field doFillXYZ method. + * + *
+ * Use one of the factory methods to create an instance, then throw it from your doFillXyz + * method. + * + * @since FIXME + */ +public abstract class FormFillFailure extends IOException implements HttpResponse { + + /** + * Sends out a string error message that indicates an error. + * + * @param message Human readable message to be sent. + */ + public static FormFillFailure error(@Nonnull String message) { + return errorWithMarkup(Util.escape(message)); + } + + public static FormFillFailure warning(@Nonnull String message) { + return warningWithMarkup(Util.escape(message)); + } + + /** + * Sends out a string error message that indicates an error, + * by formatting it with {@link String#format(String, Object[])} + */ + public static FormFillFailure error(String format, Object... args) { + return error(String.format(format, args)); + } + + public static FormFillFailure warning(String format, Object... args) { + return warning(String.format(format, args)); + } + + /** + * Sends out a string error message, with optional "show details" link that expands to the full stack trace. + * + *
+ * Use this with caution, so that anonymous users do not gain too much insights into the state of the system, + * as error stack trace often reveals a lot of information. Consider if an error needs to be exposed + * to everyone or just those who have higher access to job/hudson/etc. + */ + public static FormFillFailure error(Throwable e, String message) { + return _error(FormValidation.Kind.ERROR, e, message); + } + + public static FormFillFailure warning(Throwable e, String message) { + return _error(FormValidation.Kind.WARNING, e, message); + } + + private static FormFillFailure _error(FormValidation.Kind kind, Throwable e, String message) { + if (e == null) { + return _errorWithMarkup(Util.escape(message), kind); + } + + return _errorWithMarkup(Util.escape(message) + + " " + + Messages.FormValidation_Error_Details() + + "
", kind + ); + } + + public static FormFillFailure error(Throwable e, String format, Object... args) { + return error(e, String.format(format, args)); + } + + public static FormFillFailure warning(Throwable e, String format, Object... args) { + return warning(e, String.format(format, args)); + } + + /** + * Sends out an HTML fragment that indicates an error. + * + *+ * This method must be used with care to avoid cross-site scripting + * attack. + * + * @param message Human readable message to be sent. error(null) + * can be used as ok(). + */ + public static FormFillFailure errorWithMarkup(String message) { + return _errorWithMarkup(message, FormValidation.Kind.ERROR); + } + + public static FormFillFailure warningWithMarkup(String message) { + return _errorWithMarkup(message, FormValidation.Kind.WARNING); + } + + private static FormFillFailure _errorWithMarkup(@Nonnull final String message, final FormValidation.Kind kind) { + return new FormFillFailure(kind, message) { + public String renderHtml() { + StaplerRequest req = Stapler.getCurrentRequest(); + if (req == null) { // being called from some other context + return message; + } + // 1x16 spacer needed for IE since it doesn't support min-height + return "