diff --git a/.mvn_exec_spotless b/.mvn_exec_spotless new file mode 100644 index 0000000..e69de29 diff --git a/pom.xml b/pom.xml index 0936b5c..20f2c7b 100644 --- a/pom.xml +++ b/pom.xml @@ -4,7 +4,7 @@ org.jenkins-ci.plugins plugin - 4.58 + 4.59 io.jenkins.plugins @@ -75,41 +75,4 @@ https://repo.jenkins-ci.org/public/ - - - - - com.diffplug.spotless - spotless-maven-plugin - 2.35.0 - - - - - - - - - ${project.build.sourceEncoding} - \n - false - true - scope,groupId,artifactId - groupId,artifactId - - - - - - spotless-check - - - check - - validate - - - - - diff --git a/src/main/java/io/jenkins/plugins/thememanager/Theme.java b/src/main/java/io/jenkins/plugins/thememanager/Theme.java index 66e45d3..c952f3a 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/Theme.java +++ b/src/main/java/io/jenkins/plugins/thememanager/Theme.java @@ -21,227 +21,226 @@ */ public class Theme { - private static final String JS_HTML = ""; - private static final String CSS_HTML = - ""; - - private final List cssUrls; - private final List javascriptUrls; - private final boolean blueOceanCompatible; - private final Map properties; - - private Theme( - List cssUrls, - List javascriptUrls, - boolean blueOceanCompatible, - Map properties) { - this.cssUrls = cssUrls; - this.javascriptUrls = javascriptUrls; - this.blueOceanCompatible = blueOceanCompatible; - this.properties = properties; - } - - @Restricted(NoExternalUse.class) - Set generateHeaderElements(boolean injectCss) { - Set headerElements = new HashSet<>(); - - if (injectCss) { - for (String cssUrl : cssUrls) { - headerElements.add(MessageFormat.format(CSS_HTML, cssUrl)); - } + private static final String JS_HTML = ""; + private static final String CSS_HTML = ""; + + private final List cssUrls; + private final List javascriptUrls; + private final boolean blueOceanCompatible; + private final Map properties; + + private Theme( + List cssUrls, + List javascriptUrls, + boolean blueOceanCompatible, + Map properties) { + this.cssUrls = cssUrls; + this.javascriptUrls = javascriptUrls; + this.blueOceanCompatible = blueOceanCompatible; + this.properties = properties; } - for (String javascriptUrl : javascriptUrls) { - headerElements.add(MessageFormat.format(JS_HTML, javascriptUrl)); - } + @Restricted(NoExternalUse.class) + Set generateHeaderElements(boolean injectCss) { + Set headerElements = new HashSet<>(); - return headerElements; - } - - /** - * See {@link Builder#withCssUrl(String)} - * - * @return list of CSS URLs for the theme. - */ - public List getCssUrls() { - return cssUrls; - } - - /** - * See {@link Builder#withJavascriptUrl(String)}. - * - * @return list of JavaScript URLs for the theme. - */ - public List getJavascriptUrls() { - return javascriptUrls; - } - - /** - * Whether the theme should be served on Blue Ocean. - * - * @return if the theme is compatible with blue ocean. - */ - public boolean isBlueOceanCompatible() { - return blueOceanCompatible; - } - - /** - * Additional information that theme authors can provide to influence other plugins - * - *

e.g. the Prism API plugin can read properties and use a default theme based on this - * information. - * - * @param artifactId the plugin to retrieve the properties for - * @return the properties associated with the plugin requested - */ - public List getProperties(String artifactId) { - return properties.entrySet().stream() - .filter(k -> k.getKey().startsWith(artifactId + ":")) - .map(Map.Entry::getValue) - .collect(Collectors.toList()); - } - - /** - * Additional information that theme authors can provide to influence other plugins - * - *

e.g. the Prism API plugin can read properties and use a default theme based on this - * information. - * - * @param artifactId the plugin to retrieve the properties for - * @param propertyName the property to retrieve - * @return the properties associated with the plugin requested - */ - public Optional getProperty(String artifactId, String propertyName) { - return Optional.ofNullable(properties.get(artifactId + ":" + propertyName)); - } - - /** - * Constructs the builder for the theme. - * - * @return an empty builder for building the theme. - */ - public static Builder builder() { - return new Builder(); - } - - /** Builder for creating a theme. */ - public static class Builder { - private List cssUrls = emptyList(); - private List javascriptUrls = emptyList(); - private boolean blueOceanCompatible = false; - private final Map properties = new HashMap<>(); - - Builder() {} + if (injectCss) { + for (String cssUrl : cssUrls) { + headerElements.add(MessageFormat.format(CSS_HTML, cssUrl)); + } + } - /** - * A URL to a CSS file, this can be served by Jenkins or remote. - * - *

The URL must be absolute (i.e. not just contain the path) - * - *

It is recommended that you serve the CSS file with Jenkins so that users update the theme - * by updating the plugin. - * - *

There is a convenience method {@link ThemeManagerFactory#getCssUrl()}, which will - * determine the full url if you follow the convention: {@code - * $JENKINS_URL/theme-$themeId/theme.css}. - * - *

The {@code theme.css} suffix can be changed by overriding {@link - * ThemeManagerFactoryDescriptor#getThemeCssSuffix()}. - * - * @param cssUrl url to a CSS file that you want loaded. - * @return the current builder with a CSS URL added to it. - */ - public Builder withCssUrl(String cssUrl) { - this.cssUrls = singletonList(cssUrl); - return this; + for (String javascriptUrl : javascriptUrls) { + headerElements.add(MessageFormat.format(JS_HTML, javascriptUrl)); + } + + return headerElements; } /** - * See {@link #withCssUrl(String)} + * See {@link Builder#withCssUrl(String)} * - * @param cssUrls a list of urls to CSS files that you want loaded. - * @return the current builder with CSS URLs added to it. + * @return list of CSS URLs for the theme. */ - public Builder withCssUrls(List cssUrls) { - this.cssUrls = cssUrls; - return this; + public List getCssUrls() { + return cssUrls; } /** - * Enables the theme on BlueOcean + * See {@link Builder#withJavascriptUrl(String)}. * - * @return the current builder with BlueOcean enabled. + * @return list of JavaScript URLs for the theme. */ - public Builder enableOnBlueOcean() { - this.blueOceanCompatible = true; - return this; + public List getJavascriptUrls() { + return javascriptUrls; } /** - * Disables the theme on BlueOcean + * Whether the theme should be served on Blue Ocean. * - * @return the current builder with BlueOcean disabled. + * @return if the theme is compatible with blue ocean. */ - public Builder disableOnBlueOcean() { - this.blueOceanCompatible = false; - return this; + public boolean isBlueOceanCompatible() { + return blueOceanCompatible; } /** - * Properties are a way a theme author can provide extra information to plugins. e.g. the Prism - * API plugin can read properties and use a default theme based on this information. + * Additional information that theme authors can provide to influence other plugins + * + *

e.g. the Prism API plugin can read properties and use a default theme based on this + * information. * - * @param pluginId artifact ID of the plugin the property is associated with - * @param name property name this will be namespaced with the artifactId automatically - * @param value the property value - * @return the current builder with the new property + * @param artifactId the plugin to retrieve the properties for + * @return the properties associated with the plugin requested */ - public Builder withProperty(String pluginId, String name, String value) { - this.properties.put(pluginId + ":" + name, value); - return this; + public List getProperties(String artifactId) { + return properties.entrySet().stream() + .filter(k -> k.getKey().startsWith(artifactId + ":")) + .map(Map.Entry::getValue) + .collect(Collectors.toList()); } /** - * A URL to a JavaScript file, this can be served by Jenkins or remote. - * - *

The URL must be absolute (i.e. not just contain the path) - * - *

It is recommended that you serve the JavaScript file with Jenkins so that users update the - * theme by updating the plugin. + * Additional information that theme authors can provide to influence other plugins * - *

There is a convenience method {@link ThemeManagerFactory#getJavaScriptUrl()}, which will - * determine the full url if you follow the convention: {@code - * $JENKINS_URL/theme-$themeId/theme.js}. + *

e.g. the Prism API plugin can read properties and use a default theme based on this + * information. * - *

The {@code theme.css} suffix can be changed by overriding {@link - * ThemeManagerFactoryDescriptor#getThemeJsSuffix()}. - * - * @param javascriptUrl url to a JavaScript file that you want loaded. - * @return the current builder with a JavaScript URL added to it. + * @param artifactId the plugin to retrieve the properties for + * @param propertyName the property to retrieve + * @return the properties associated with the plugin requested */ - public Builder withJavascriptUrl(String javascriptUrl) { - this.javascriptUrls = singletonList(javascriptUrl); - return this; + public Optional getProperty(String artifactId, String propertyName) { + return Optional.ofNullable(properties.get(artifactId + ":" + propertyName)); } /** - * See {@link #withJavascriptUrl(String)}. + * Constructs the builder for the theme. * - * @param javascriptUrls a list of urls to JavaScript files that you want loaded. - * @return the current builder with JavaScript URLs added to it. + * @return an empty builder for building the theme. */ - public Builder withJavascriptUrls(List javascriptUrls) { - this.javascriptUrls = javascriptUrls; - return this; + public static Builder builder() { + return new Builder(); } - /** - * Constructs the theme - * - * @return the theme. - */ - public Theme build() { - return new Theme(cssUrls, javascriptUrls, blueOceanCompatible, properties); + /** Builder for creating a theme. */ + public static class Builder { + private List cssUrls = emptyList(); + private List javascriptUrls = emptyList(); + private boolean blueOceanCompatible = false; + private final Map properties = new HashMap<>(); + + Builder() {} + + /** + * A URL to a CSS file, this can be served by Jenkins or remote. + * + *

The URL must be absolute (i.e. not just contain the path) + * + *

It is recommended that you serve the CSS file with Jenkins so that users update the theme + * by updating the plugin. + * + *

There is a convenience method {@link ThemeManagerFactory#getCssUrl()}, which will + * determine the full url if you follow the convention: {@code + * $JENKINS_URL/theme-$themeId/theme.css}. + * + *

The {@code theme.css} suffix can be changed by overriding {@link + * ThemeManagerFactoryDescriptor#getThemeCssSuffix()}. + * + * @param cssUrl url to a CSS file that you want loaded. + * @return the current builder with a CSS URL added to it. + */ + public Builder withCssUrl(String cssUrl) { + this.cssUrls = singletonList(cssUrl); + return this; + } + + /** + * See {@link #withCssUrl(String)} + * + * @param cssUrls a list of urls to CSS files that you want loaded. + * @return the current builder with CSS URLs added to it. + */ + public Builder withCssUrls(List cssUrls) { + this.cssUrls = cssUrls; + return this; + } + + /** + * Enables the theme on BlueOcean + * + * @return the current builder with BlueOcean enabled. + */ + public Builder enableOnBlueOcean() { + this.blueOceanCompatible = true; + return this; + } + + /** + * Disables the theme on BlueOcean + * + * @return the current builder with BlueOcean disabled. + */ + public Builder disableOnBlueOcean() { + this.blueOceanCompatible = false; + return this; + } + + /** + * Properties are a way a theme author can provide extra information to plugins. e.g. the Prism + * API plugin can read properties and use a default theme based on this information. + * + * @param pluginId artifact ID of the plugin the property is associated with + * @param name property name this will be namespaced with the artifactId automatically + * @param value the property value + * @return the current builder with the new property + */ + public Builder withProperty(String pluginId, String name, String value) { + this.properties.put(pluginId + ":" + name, value); + return this; + } + + /** + * A URL to a JavaScript file, this can be served by Jenkins or remote. + * + *

The URL must be absolute (i.e. not just contain the path) + * + *

It is recommended that you serve the JavaScript file with Jenkins so that users update the + * theme by updating the plugin. + * + *

There is a convenience method {@link ThemeManagerFactory#getJavaScriptUrl()}, which will + * determine the full url if you follow the convention: {@code + * $JENKINS_URL/theme-$themeId/theme.js}. + * + *

The {@code theme.css} suffix can be changed by overriding {@link + * ThemeManagerFactoryDescriptor#getThemeJsSuffix()}. + * + * @param javascriptUrl url to a JavaScript file that you want loaded. + * @return the current builder with a JavaScript URL added to it. + */ + public Builder withJavascriptUrl(String javascriptUrl) { + this.javascriptUrls = singletonList(javascriptUrl); + return this; + } + + /** + * See {@link #withJavascriptUrl(String)}. + * + * @param javascriptUrls a list of urls to JavaScript files that you want loaded. + * @return the current builder with JavaScript URLs added to it. + */ + public Builder withJavascriptUrls(List javascriptUrls) { + this.javascriptUrls = javascriptUrls; + return this; + } + + /** + * Constructs the theme + * + * @return the theme. + */ + public Theme build() { + return new Theme(cssUrls, javascriptUrls, blueOceanCompatible, properties); + } } - } } diff --git a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerBluePageDecorator.java b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerBluePageDecorator.java index 358a13a..5608e1c 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerBluePageDecorator.java +++ b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerBluePageDecorator.java @@ -9,23 +9,23 @@ @Restricted(NoExternalUse.class) public class ThemeManagerBluePageDecorator extends BluePageDecorator { - public String getHeaderHtml() { - ThemeManagerPageDecorator themeManagerPageDecorator = ThemeManagerPageDecorator.get(); - Theme theme = themeManagerPageDecorator.findTheme(); + public String getHeaderHtml() { + ThemeManagerPageDecorator themeManagerPageDecorator = ThemeManagerPageDecorator.get(); + Theme theme = themeManagerPageDecorator.findTheme(); - if (theme.isBlueOceanCompatible()) { - return themeManagerPageDecorator.getHeaderHtml(); + if (theme.isBlueOceanCompatible()) { + return themeManagerPageDecorator.getHeaderHtml(); + } + return null; } - return null; - } - public String getThemeKey() { - ThemeManagerPageDecorator themeManagerPageDecorator = ThemeManagerPageDecorator.get(); - Theme theme = themeManagerPageDecorator.findTheme(); + public String getThemeKey() { + ThemeManagerPageDecorator themeManagerPageDecorator = ThemeManagerPageDecorator.get(); + Theme theme = themeManagerPageDecorator.findTheme(); - if (theme.isBlueOceanCompatible()) { - return themeManagerPageDecorator.getThemeKey(); + if (theme.isBlueOceanCompatible()) { + return themeManagerPageDecorator.getThemeKey(); + } + return null; } - return null; - } } diff --git a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactory.java b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactory.java index bcb0e61..9b04d5b 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactory.java +++ b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactory.java @@ -15,50 +15,50 @@ * @see ThemeManagerPageDecorator */ public abstract class ThemeManagerFactory extends AbstractDescribableImpl - implements ExtensionPoint { + implements ExtensionPoint { - public abstract Theme getTheme(); + public abstract Theme getTheme(); - /** - * Expected CSS URL assuming your CSS file is named after your theme. You can also change the CSS - * file name by overriding: {@link ThemeManagerFactoryDescriptor#getThemeCssSuffix()} - * - *

See {@link #toAssetUrl(String)} for arbitrary files - * - * @return CSS url in the form '$JENKINS_URL/theme-$themeId/theme.css. - */ - public String getCssUrl() { - ThemeManagerFactoryDescriptor descriptor = getDescriptor(); - return toAssetUrl(descriptor.getThemeCssSuffix()); - } + /** + * Expected CSS URL assuming your CSS file is named after your theme. You can also change the CSS + * file name by overriding: {@link ThemeManagerFactoryDescriptor#getThemeCssSuffix()} + * + *

See {@link #toAssetUrl(String)} for arbitrary files + * + * @return CSS url in the form '$JENKINS_URL/theme-$themeId/theme.css. + */ + public String getCssUrl() { + ThemeManagerFactoryDescriptor descriptor = getDescriptor(); + return toAssetUrl(descriptor.getThemeCssSuffix()); + } - /** - * Arbitrary asset URL. Useful if you want additional css or js files - * - * @param asset additional-stylesheet.css - * @return Asset url in the form '$JENKINS_URL/theme-$themeId/$asset-parameter - */ - public String toAssetUrl(String asset) { - ThemeManagerFactoryDescriptor descriptor = getDescriptor(); - return Jenkins.get().getRootUrl() + "theme-" + descriptor.getThemeId() + "/" + asset; - } + /** + * Arbitrary asset URL. Useful if you want additional css or js files + * + * @param asset additional-stylesheet.css + * @return Asset url in the form '$JENKINS_URL/theme-$themeId/$asset-parameter + */ + public String toAssetUrl(String asset) { + ThemeManagerFactoryDescriptor descriptor = getDescriptor(); + return Jenkins.get().getRootUrl() + "theme-" + descriptor.getThemeId() + "/" + asset; + } - /** - * Expected JavaScript URL assuming your JavaScript file is named after your theme. You can also - * change the CSS file name by overriding: {@link - * ThemeManagerFactoryDescriptor#getThemeJsSuffix()} - * - *

See {@link #toAssetUrl(String)} for arbitrary files - * - * @return JavaScript url in the form '$JENKINS_URL/theme-$themeId/theme.js. - */ - public String getJavaScriptUrl() { - ThemeManagerFactoryDescriptor descriptor = getDescriptor(); - return toAssetUrl(descriptor.getThemeJsSuffix()); - } + /** + * Expected JavaScript URL assuming your JavaScript file is named after your theme. You can also + * change the CSS file name by overriding: {@link + * ThemeManagerFactoryDescriptor#getThemeJsSuffix()} + * + *

See {@link #toAssetUrl(String)} for arbitrary files + * + * @return JavaScript url in the form '$JENKINS_URL/theme-$themeId/theme.js. + */ + public String getJavaScriptUrl() { + ThemeManagerFactoryDescriptor descriptor = getDescriptor(); + return toAssetUrl(descriptor.getThemeJsSuffix()); + } - @Override - public ThemeManagerFactoryDescriptor getDescriptor() { - return (ThemeManagerFactoryDescriptor) super.getDescriptor(); - } + @Override + public ThemeManagerFactoryDescriptor getDescriptor() { + return (ThemeManagerFactoryDescriptor) super.getDescriptor(); + } } diff --git a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactoryDescriptor.java b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactoryDescriptor.java index 6eeaf76..75ffe6f 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactoryDescriptor.java +++ b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerFactoryDescriptor.java @@ -11,84 +11,84 @@ */ public abstract class ThemeManagerFactoryDescriptor extends Descriptor { - public ThemeManagerFactory getInstance() { - try { - //noinspection deprecation - return this.clazz.newInstance(); - } catch (InstantiationException | IllegalAccessException e) { - throw new IllegalStateException("Failed to instantiate " + clazz.getName(), e); + public ThemeManagerFactory getInstance() { + try { + //noinspection deprecation + return this.clazz.newInstance(); + } catch (InstantiationException | IllegalAccessException e) { + throw new IllegalStateException("Failed to instantiate " + clazz.getName(), e); + } } - } - /** - * A name for a theme plugin - * - *

This should be all lower case and URL safe, i.e. 'dark', 'neo2' - * - *

The ID can be re-used inside of your plugin if you are serving multiple variations of the - * theme, i.e. 'Dark', 'Dark (System)' could both be 'dark'. - * - *

Used in generating URLs for Jenkins to find your theme files. - * - * @return the theme ID. - */ - public abstract String getThemeId(); + /** + * A name for a theme plugin + * + *

This should be all lower case and URL safe, i.e. 'dark', 'neo2' + * + *

The ID can be re-used inside of your plugin if you are serving multiple variations of the + * theme, i.e. 'Dark', 'Dark (System)' could both be 'dark'. + * + *

Used in generating URLs for Jenkins to find your theme files. + * + * @return the theme ID. + */ + public abstract String getThemeId(); - /** - * A unique key for a theme plugin - * - *

This should be all lower case and URL safe, i.e. 'dark-system', 'neo2' - * - *

Used in the html dataset namespace for the theme. - * - * @return the theme key - */ - public String getThemeKey() { - return getThemeId(); - } + /** + * A unique key for a theme plugin + * + *

This should be all lower case and URL safe, i.e. 'dark-system', 'neo2' + * + *

Used in the html dataset namespace for the theme. + * + * @return the theme key + */ + public String getThemeKey() { + return getThemeId(); + } - /** - * If the theme's CSS will only be selected under the '[data-theme=theme-key]' selector - * - *

It will be served on all pages even if not activated, ensure all selectors are behind the - * dataset selector. - * - *

All new themes should be namespaced - * - * @return if it's namespaced. - */ - public boolean isNamespaced() { - return false; - } + /** + * If the theme's CSS will only be selected under the '[data-theme=theme-key]' selector + * + *

It will be served on all pages even if not activated, ensure all selectors are behind the + * dataset selector. + * + *

All new themes should be namespaced + * + * @return if it's namespaced. + */ + public boolean isNamespaced() { + return false; + } - /** - * Name of the theme resource file. - * - *

Used in generating URLs for Jenkins to find your theme files. - * - * @return name of the theme resource file. - */ - public String getThemeCssSuffix() { - return "theme.css"; - } + /** + * Name of the theme resource file. + * + *

Used in generating URLs for Jenkins to find your theme files. + * + * @return name of the theme resource file. + */ + public String getThemeCssSuffix() { + return "theme.css"; + } - /** - * Name of the theme resource file. - * - *

Used in generating URLs for Jenkins to find your theme files. - * - * @return name of the theme resource file. - */ - public String getThemeJsSuffix() { - return "theme.js"; - } + /** + * Name of the theme resource file. + * + *

Used in generating URLs for Jenkins to find your theme files. + * + * @return name of the theme resource file. + */ + public String getThemeJsSuffix() { + return "theme.js"; + } - /** - * All implementations of {@link ThemeManagerFactory} and {@link ThemeManagerFactoryDescriptor}. - * - * @return descriptor extension list containing all themes. - */ - public static DescriptorExtensionList all() { - return Jenkins.get().getDescriptorList(ThemeManagerFactory.class); - } + /** + * All implementations of {@link ThemeManagerFactory} and {@link ThemeManagerFactoryDescriptor}. + * + * @return descriptor extension list containing all themes. + */ + public static DescriptorExtensionList all() { + return Jenkins.get().getDescriptorList(ThemeManagerFactory.class); + } } diff --git a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerPageDecorator.java b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerPageDecorator.java index c5b7f78..2ac8c04 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerPageDecorator.java +++ b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerPageDecorator.java @@ -21,126 +21,125 @@ @Symbol("themeManager") public class ThemeManagerPageDecorator extends PageDecorator { - private ThemeManagerFactory theme; - private boolean disableUserThemes; - - public ThemeManagerPageDecorator() { - load(); - } - - public static ThemeManagerPageDecorator get() { - return ExtensionList.lookupSingleton(ThemeManagerPageDecorator.class); - } - - @Override - public boolean configure(StaplerRequest req, JSONObject formData) { - req.bindJSON(this, formData); - save(); - return true; - } - - @DataBoundSetter - public void setTheme(ThemeManagerFactory theme) { - this.theme = theme; - } - - public ThemeManagerFactory getTheme() { - return theme; - } - - public boolean isDisableUserThemes() { - return disableUserThemes; - } - - @DataBoundSetter - public void setDisableUserThemes(boolean disableUserThemes) { - this.disableUserThemes = disableUserThemes; - } - - /** - * Finds the active theme. Checks User and then global theme. - * - * @return the active theme, or a no-op theme if not selected - */ - @NonNull - public Theme findTheme() { - if (!disableUserThemes) { - Theme userTheme = ThemeUserProperty.forCurrentUser(); - if (userTheme != null) { - return userTheme; - } + private ThemeManagerFactory theme; + private boolean disableUserThemes; + + public ThemeManagerPageDecorator() { + load(); + } + + public static ThemeManagerPageDecorator get() { + return ExtensionList.lookupSingleton(ThemeManagerPageDecorator.class); + } + + @Override + public boolean configure(StaplerRequest req, JSONObject formData) { + req.bindJSON(this, formData); + save(); + return true; + } + + @DataBoundSetter + public void setTheme(ThemeManagerFactory theme) { + this.theme = theme; } - if (theme != null) { - return theme.getTheme(); + public ThemeManagerFactory getTheme() { + return theme; } - return new NoOpThemeManagerFactory().getTheme(); - } - - @NonNull - public ThemeManagerFactory findThemeFactory() { - if (!disableUserThemes) { - ThemeManagerFactory userTheme = ThemeUserProperty.forCurrentUserFactory(); - if (userTheme != null) { - return userTheme; - } + + public boolean isDisableUserThemes() { + return disableUserThemes; } - if (theme != null) { - return theme; + @DataBoundSetter + public void setDisableUserThemes(boolean disableUserThemes) { + this.disableUserThemes = disableUserThemes; } - return new NoOpThemeManagerFactory(); - } - - /** Get the complete header HTML for all configured theme elements. */ - public String getHeaderHtml() { - boolean injectCss = shouldInjectCss(); - Set namespacedThemes = - ThemeManagerFactoryDescriptor.all().stream() - .filter(ThemeManagerFactoryDescriptor::isNamespaced) - .map(desc -> desc.getInstance().getTheme().generateHeaderElements(injectCss)) - .flatMap(Set::stream) - .collect(Collectors.toSet()); - - ThemeManagerFactory themeManagerFactory = findThemeFactory(); - if (!themeManagerFactory.getDescriptor().isNamespaced()) { - Set data = - new LinkedHashSet<>(themeManagerFactory.getTheme().generateHeaderElements(injectCss)); - data.addAll(namespacedThemes); - return StringUtils.join(data, "\n"); + + /** + * Finds the active theme. Checks User and then global theme. + * + * @return the active theme, or a no-op theme if not selected + */ + @NonNull + public Theme findTheme() { + if (!disableUserThemes) { + Theme userTheme = ThemeUserProperty.forCurrentUser(); + if (userTheme != null) { + return userTheme; + } + } + + if (theme != null) { + return theme.getTheme(); + } + return new NoOpThemeManagerFactory().getTheme(); } - return StringUtils.join(namespacedThemes, "\n"); - } - - @SuppressWarnings("unused") // called by jelly - public String getThemeKey() { - ThemeManagerFactory themeFactory = findThemeFactory(); - - return themeFactory.getDescriptor().getThemeKey(); - } - - /** - * Filter to only inject CSS into "normal" Jenkins pages. Some plugins replace the whole layout of - * Jenkins and we don't want to disturb them. - * - * @return true if it is okay to inject CSS - */ - public boolean shouldInjectCss() { - StaplerRequest req = Stapler.getCurrentRequest(); - if (req == null) { - return false; + @NonNull + public ThemeManagerFactory findThemeFactory() { + if (!disableUserThemes) { + ThemeManagerFactory userTheme = ThemeUserProperty.forCurrentUserFactory(); + if (userTheme != null) { + return userTheme; + } + } + + if (theme != null) { + return theme; + } + return new NoOpThemeManagerFactory(); } - List ancestors = req.getAncestors(); - if (ancestors == null || ancestors.size() == 0) { - return false; + /** Get the complete header HTML for all configured theme elements. */ + public String getHeaderHtml() { + boolean injectCss = shouldInjectCss(); + Set namespacedThemes = ThemeManagerFactoryDescriptor.all().stream() + .filter(ThemeManagerFactoryDescriptor::isNamespaced) + .map(desc -> desc.getInstance().getTheme().generateHeaderElements(injectCss)) + .flatMap(Set::stream) + .collect(Collectors.toSet()); + + ThemeManagerFactory themeManagerFactory = findThemeFactory(); + if (!themeManagerFactory.getDescriptor().isNamespaced()) { + Set data = + new LinkedHashSet<>(themeManagerFactory.getTheme().generateHeaderElements(injectCss)); + data.addAll(namespacedThemes); + return StringUtils.join(data, "\n"); + } + + return StringUtils.join(namespacedThemes, "\n"); } - Ancestor a = ancestors.get(ancestors.size() - 1); - Object o = a.getObject(); + @SuppressWarnings("unused") // called by jelly + public String getThemeKey() { + ThemeManagerFactory themeFactory = findThemeFactory(); - // We don't want to style the build-monitor-plugin - return !o.getClass().getName().startsWith("com.smartcodeltd.jenkinsci.plugins.buildmonitor"); - } + return themeFactory.getDescriptor().getThemeKey(); + } + + /** + * Filter to only inject CSS into "normal" Jenkins pages. Some plugins replace the whole layout of + * Jenkins and we don't want to disturb them. + * + * @return true if it is okay to inject CSS + */ + public boolean shouldInjectCss() { + StaplerRequest req = Stapler.getCurrentRequest(); + if (req == null) { + return false; + } + + List ancestors = req.getAncestors(); + if (ancestors == null || ancestors.size() == 0) { + return false; + } + + Ancestor a = ancestors.get(ancestors.size() - 1); + Object o = a.getObject(); + + // We don't want to style the build-monitor-plugin + return !o.getClass().getName().startsWith("com.smartcodeltd.jenkinsci.plugins.buildmonitor"); + } } diff --git a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerSimplePageDecorator.java b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerSimplePageDecorator.java index d3995e2..8097ae3 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerSimplePageDecorator.java +++ b/src/main/java/io/jenkins/plugins/thememanager/ThemeManagerSimplePageDecorator.java @@ -9,15 +9,15 @@ @Restricted(NoExternalUse.class) public class ThemeManagerSimplePageDecorator extends SimplePageDecorator { - public ThemeManagerSimplePageDecorator() { - load(); - } + public ThemeManagerSimplePageDecorator() { + load(); + } - public String getHeaderHtml() { - return ThemeManagerPageDecorator.get().getHeaderHtml(); - } + public String getHeaderHtml() { + return ThemeManagerPageDecorator.get().getHeaderHtml(); + } - public String getThemeKey() { - return ThemeManagerPageDecorator.get().getThemeKey(); - } + public String getThemeKey() { + return ThemeManagerPageDecorator.get().getThemeKey(); + } } diff --git a/src/main/java/io/jenkins/plugins/thememanager/ThemeUserProperty.java b/src/main/java/io/jenkins/plugins/thememanager/ThemeUserProperty.java index 804af88..7c8fecd 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/ThemeUserProperty.java +++ b/src/main/java/io/jenkins/plugins/thememanager/ThemeUserProperty.java @@ -14,61 +14,61 @@ @Restricted(NoExternalUse.class) public class ThemeUserProperty extends UserProperty { - private ThemeManagerFactory theme; + private ThemeManagerFactory theme; - @DataBoundConstructor - public ThemeUserProperty() {} + @DataBoundConstructor + public ThemeUserProperty() {} - public ThemeManagerFactory getTheme() { - return theme; - } - - @DataBoundSetter - public void setTheme(ThemeManagerFactory theme) { - this.theme = theme; - } - - @CheckForNull - public static Theme forCurrentUser() { - ThemeManagerFactory factory = forCurrentUserFactory(); - if (factory == null) { - return null; + public ThemeManagerFactory getTheme() { + return theme; } - return factory.getTheme(); - } - @CheckForNull - public static ThemeManagerFactory forCurrentUserFactory() { - final User current = User.current(); - if (current == null) { - return null; + @DataBoundSetter + public void setTheme(ThemeManagerFactory theme) { + this.theme = theme; } - ThemeUserProperty property = current.getProperty(ThemeUserProperty.class); - if (property == null || property.theme == null) { - return null; + @CheckForNull + public static Theme forCurrentUser() { + ThemeManagerFactory factory = forCurrentUserFactory(); + if (factory == null) { + return null; + } + return factory.getTheme(); } - return property.getTheme(); - } + @CheckForNull + public static ThemeManagerFactory forCurrentUserFactory() { + final User current = User.current(); + if (current == null) { + return null; + } - @Extension - public static class ThemeUserPropertyDescriptor extends UserPropertyDescriptor { + ThemeUserProperty property = current.getProperty(ThemeUserProperty.class); + if (property == null || property.theme == null) { + return null; + } - @Override - public boolean isEnabled() { - return !ThemeManagerPageDecorator.get().isDisableUserThemes(); + return property.getTheme(); } - @NonNull - @Override - public String getDisplayName() { - return "Themes"; - } + @Extension + public static class ThemeUserPropertyDescriptor extends UserPropertyDescriptor { + + @Override + public boolean isEnabled() { + return !ThemeManagerPageDecorator.get().isDisableUserThemes(); + } + + @NonNull + @Override + public String getDisplayName() { + return "Themes"; + } - @Override - public UserProperty newInstance(User user) { - return new ThemeUserProperty(); + @Override + public UserProperty newInstance(User user) { + return new ThemeUserProperty(); + } } - } } diff --git a/src/main/java/io/jenkins/plugins/thememanager/none/NoOpThemeManagerFactory.java b/src/main/java/io/jenkins/plugins/thememanager/none/NoOpThemeManagerFactory.java index 814022a..57284e2 100644 --- a/src/main/java/io/jenkins/plugins/thememanager/none/NoOpThemeManagerFactory.java +++ b/src/main/java/io/jenkins/plugins/thememanager/none/NoOpThemeManagerFactory.java @@ -13,31 +13,31 @@ @Restricted(NoExternalUse.class) public class NoOpThemeManagerFactory extends ThemeManagerFactory { - @DataBoundConstructor - public NoOpThemeManagerFactory() {} + @DataBoundConstructor + public NoOpThemeManagerFactory() {} - @Override - public Theme getTheme() { - return Theme.builder().build(); - } - - @Extension - public static class NoOpThemeManagerFactoryDescriptor extends ThemeManagerFactoryDescriptor { - - @NonNull @Override - public String getDisplayName() { - return "Default"; + public Theme getTheme() { + return Theme.builder().build(); } - @Override - public String getThemeId() { - return "none"; - } + @Extension + public static class NoOpThemeManagerFactoryDescriptor extends ThemeManagerFactoryDescriptor { - @Override - public String getThemeKey() { - return "none"; + @NonNull + @Override + public String getDisplayName() { + return "Default"; + } + + @Override + public String getThemeId() { + return "none"; + } + + @Override + public String getThemeKey() { + return "none"; + } } - } } diff --git a/src/test/java/io/jenkins/plugins/thememanager/ThemeManagerJcascTest.java b/src/test/java/io/jenkins/plugins/thememanager/ThemeManagerJcascTest.java index a4bc393..84b7891 100644 --- a/src/test/java/io/jenkins/plugins/thememanager/ThemeManagerJcascTest.java +++ b/src/test/java/io/jenkins/plugins/thememanager/ThemeManagerJcascTest.java @@ -19,30 +19,30 @@ public class ThemeManagerJcascTest { - @ClassRule - @ConfiguredWithCode("ConfigurationAsCode.yml") - public static JenkinsConfiguredWithCodeRule j = new JenkinsConfiguredWithCodeRule(); + @ClassRule + @ConfiguredWithCode("ConfigurationAsCode.yml") + public static JenkinsConfiguredWithCodeRule j = new JenkinsConfiguredWithCodeRule(); - @Test - public void testConfig() { - ThemeManagerPageDecorator decorator = ThemeManagerPageDecorator.get(); + @Test + public void testConfig() { + ThemeManagerPageDecorator decorator = ThemeManagerPageDecorator.get(); - ThemeManagerFactory theme = decorator.getTheme(); - assertNotNull(theme); + ThemeManagerFactory theme = decorator.getTheme(); + assertNotNull(theme); - assertThat(decorator.isDisableUserThemes(), is(true)); - assertThat(theme, instanceOf(NoOpThemeManagerFactory.class)); - } + assertThat(decorator.isDisableUserThemes(), is(true)); + assertThat(theme, instanceOf(NoOpThemeManagerFactory.class)); + } - @Test - public void testExport() throws Exception { - ConfigurationContext context = new ConfigurationContext(ConfiguratorRegistry.get()); - CNode yourAttribute = getUnclassifiedRoot(context).get("themeManager"); + @Test + public void testExport() throws Exception { + ConfigurationContext context = new ConfigurationContext(ConfiguratorRegistry.get()); + CNode yourAttribute = getUnclassifiedRoot(context).get("themeManager"); - String exported = toYamlString(yourAttribute); + String exported = toYamlString(yourAttribute); - String expected = toStringFromYamlFile(this, "ConfigurationAsCodeExport.yml"); + String expected = toStringFromYamlFile(this, "ConfigurationAsCodeExport.yml"); - assertThat(exported, is(expected)); - } + assertThat(exported, is(expected)); + } } diff --git a/src/test/java/io/jenkins/plugins/thememanager/ThemeTest.java b/src/test/java/io/jenkins/plugins/thememanager/ThemeTest.java index 2702a75..d51c577 100644 --- a/src/test/java/io/jenkins/plugins/thememanager/ThemeTest.java +++ b/src/test/java/io/jenkins/plugins/thememanager/ThemeTest.java @@ -8,19 +8,20 @@ public class ThemeTest { - @Test - public void getPropertyReturnsKeyIfPresent() { - Theme theme = Theme.builder().withProperty("prism-api", "theme", "some-theme").build(); + @Test + public void getPropertyReturnsKeyIfPresent() { + Theme theme = + Theme.builder().withProperty("prism-api", "theme", "some-theme").build(); - Optional property = theme.getProperty("prism-api", "theme"); - assertThat(property, is(Optional.of("some-theme"))); - } + Optional property = theme.getProperty("prism-api", "theme"); + assertThat(property, is(Optional.of("some-theme"))); + } - @Test - public void getPropertyReturnsOptionalIfNotPresent() { - Theme theme = Theme.builder().build(); + @Test + public void getPropertyReturnsOptionalIfNotPresent() { + Theme theme = Theme.builder().build(); - Optional property = theme.getProperty("prism-api", "theme"); - assertThat(property, is(Optional.empty())); - } + Optional property = theme.getProperty("prism-api", "theme"); + assertThat(property, is(Optional.empty())); + } }