/*
* The MIT License
*
* Copyright (c) 2011, 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.Extension;
import hudson.ExtensionList;
import hudson.ExtensionPoint;
import hudson.model.AbstractProject;
/**
* Provides the alternative text to be rendered in the UI.
*
* <p>
* In a few limited places in Jenkins, we want to provide an ability for plugins to replace
* the text to be shown in the UI. Since each such case is rather trivial and can't justify
* its own extension point, we consolidate all such use cases into a single extension point.
*
* <p>
* Each such overridable UI text can have a context, which represents some information
* that enables the {@link AlternativeUiTextProvider} to make intelligent decision. This
* is normally some kind of a model object, such as {@link AbstractProject}.
*
* <p>
* To define a new UI text that can be overridable by {@link AlternativeUiTextProvider},
* define a constant of {@link Message} (parameterized with the context object type),
* then call {@link #get(Message, Object)} to obtain a text.
*
* <p>
* To define an implementation that overrides text, define a subtype and put @{@link Extension} on it.
* See {@link AbstractProject#getBuildNowText()} as an example.
*
* @author Kohsuke Kawaguchi
* @since 1.401
*/
public abstract class AlternativeUiTextProvider implements ExtensionPoint {
/**
* Provides an opportunity to override the message text.
*
* @param text
* Always non-null. Caller should pass in a {@link Message} constant that
* represents the text that we are being considered.
* @param context
* Context object. See class javadoc above.
*/
public abstract <T> String getText(Message<T> text, T context);
/**
* All the registered extension point instances.
*/
public static ExtensionList<AlternativeUiTextProvider> all() {
return ExtensionList.lookup(AlternativeUiTextProvider.class);
}
public static <T> String get(Message<T> text, T context, String defaultValue) {
String s = get(text,context);
return s!=null ? s : defaultValue;
}
/**
* Consults all the existing {@link AlternativeUiTextProvider} and return an override, if any,
* or null.
*/
public static <T> String get(Message<T> text, T context) {
for (AlternativeUiTextProvider p : all()) {
String s = p.getText(text, context);
if (s!=null)
return s;
}
return null;
}
/**
* Each instance of this class represents a text that can be replaced by {@link AlternativeUiTextProvider}.
*
* @param <T>
* Context object type. Use {@link Void} to indicate that there's no context.
*/
public static final class Message<T> {
// decided not to retain T as Class so that we can have Message<List<Foo>>, for example.
/**
* Assists pattern matching in the {@link AlternativeUiTextProvider} implementation.
*/
@SuppressWarnings({"unchecked"})
public T cast(Object context) {
return (T)context;
}
}
}