Support image based banners
Add ImageBanner class that generates color ASCII art based on an image file (banner.gif, banner.jpg or banner.png). See gh-4647
This commit is contained in:
parent
6550bb4cf1
commit
58d77ec961
|
@ -0,0 +1,249 @@
|
|||
/*
|
||||
* Copyright 2012-2015 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.boot;
|
||||
|
||||
import java.awt.Color;
|
||||
import java.awt.Image;
|
||||
|
||||
import java.awt.image.BufferedImage;
|
||||
|
||||
import java.io.PrintStream;
|
||||
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
import java.util.Map.Entry;
|
||||
|
||||
import javax.imageio.ImageIO;
|
||||
|
||||
import org.apache.commons.logging.Log;
|
||||
import org.apache.commons.logging.LogFactory;
|
||||
|
||||
import org.springframework.boot.ansi.AnsiPropertySource;
|
||||
import org.springframework.core.env.Environment;
|
||||
import org.springframework.core.env.MutablePropertySources;
|
||||
import org.springframework.core.env.PropertyResolver;
|
||||
import org.springframework.core.env.PropertySourcesPropertyResolver;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.util.Assert;
|
||||
|
||||
/**
|
||||
* Banner implementation that prints ASCII art generated from an image resource
|
||||
* {@link Resource}.
|
||||
*
|
||||
* @author Craig Burke
|
||||
*/
|
||||
public class ImageBanner implements Banner {
|
||||
|
||||
private static final Log log = LogFactory.getLog(ImageBanner.class);
|
||||
|
||||
private static final double RED_WEIGHT = 0.2126d;
|
||||
private static final double GREEN_WEIGHT = 0.7152d;
|
||||
private static final double BLUE_WEIGHT = 0.0722d;
|
||||
|
||||
private static final int DEFAULT_MAX_WIDTH = 72;
|
||||
private static final double DEFAULT_ASPECT_RATIO = 0.5d;
|
||||
private static final boolean DEFAULT_DARK = false;
|
||||
|
||||
private Resource image;
|
||||
private Map<String, Color> colors = new HashMap<String, Color>();
|
||||
|
||||
public ImageBanner(Resource image) {
|
||||
Assert.notNull(image, "Image must not be null");
|
||||
Assert.isTrue(image.exists(), "Image must exist");
|
||||
this.image = image;
|
||||
colorsInit();
|
||||
}
|
||||
|
||||
private void colorsInit() {
|
||||
this.colors.put("BLACK", new Color(0, 0, 0));
|
||||
this.colors.put("RED", new Color(170, 0, 0));
|
||||
this.colors.put("GREEN", new Color(0, 170, 0));
|
||||
this.colors.put("YELLOW", new Color(170, 85, 0));
|
||||
this.colors.put("BLUE", new Color(0, 0, 170));
|
||||
this.colors.put("MAGENTA", new Color(170, 0, 170));
|
||||
this.colors.put("CYAN", new Color(0, 170, 170));
|
||||
this.colors.put("WHITE", new Color(170, 170, 170));
|
||||
|
||||
this.colors.put("BRIGHT_BLACK", new Color(85, 85, 85));
|
||||
this.colors.put("BRIGHT_RED", new Color(255, 85, 85));
|
||||
this.colors.put("BRIGHT_GREEN", new Color(85, 255, 85));
|
||||
this.colors.put("BRIGHT_YELLOW", new Color(255, 255, 85));
|
||||
this.colors.put("BRIGHT_BLUE", new Color(85, 85, 255));
|
||||
this.colors.put("BRIGHT_MAGENTA", new Color(255, 85, 255));
|
||||
this.colors.put("BRIGHT_CYAN", new Color(85, 255, 255));
|
||||
this.colors.put("BRIGHT_WHITE", new Color(255, 255, 255));
|
||||
}
|
||||
|
||||
@Override
|
||||
public void printBanner(Environment environment, Class<?> sourceClass, PrintStream out) {
|
||||
String headlessProperty = System.getProperty("java.awt.headless");
|
||||
try {
|
||||
System.setProperty("java.awt.headless", "true");
|
||||
BufferedImage sourceImage = ImageIO.read(this.image.getInputStream());
|
||||
|
||||
int maxWidth = environment.getProperty("banner.image.max-width",
|
||||
Integer.class, DEFAULT_MAX_WIDTH);
|
||||
Double aspectRatio = environment.getProperty("banner.image.aspect-ratio",
|
||||
Double.class, DEFAULT_ASPECT_RATIO);
|
||||
boolean invert = environment.getProperty("banner.image.dark", Boolean.class,
|
||||
DEFAULT_DARK);
|
||||
|
||||
BufferedImage resizedImage = resizeImage(sourceImage, maxWidth, aspectRatio);
|
||||
String banner = imageToBanner(resizedImage, invert);
|
||||
|
||||
PropertyResolver ansiResolver = getAnsiResolver();
|
||||
banner = ansiResolver.resolvePlaceholders(banner);
|
||||
out.println(banner);
|
||||
}
|
||||
catch (Exception ex) {
|
||||
log.warn("Image banner not printable: " + this.image + " (" + ex.getClass()
|
||||
+ ": '" + ex.getMessage() + "')", ex);
|
||||
}
|
||||
finally {
|
||||
System.setProperty("java.awt.headless", headlessProperty);
|
||||
}
|
||||
}
|
||||
|
||||
private PropertyResolver getAnsiResolver() {
|
||||
MutablePropertySources sources = new MutablePropertySources();
|
||||
sources.addFirst(new AnsiPropertySource("ansi", true));
|
||||
return new PropertySourcesPropertyResolver(sources);
|
||||
}
|
||||
|
||||
private String imageToBanner(BufferedImage image, boolean dark) {
|
||||
StringBuilder banner = new StringBuilder();
|
||||
|
||||
for (int y = 0; y < image.getHeight(); y++) {
|
||||
if (dark) {
|
||||
banner.append("${AnsiBackground.BLACK}");
|
||||
}
|
||||
else {
|
||||
banner.append("${AnsiBackground.DEFAULT}");
|
||||
}
|
||||
for (int x = 0; x < image.getWidth(); x++) {
|
||||
Color color = new Color(image.getRGB(x, y), false);
|
||||
banner.append(getFormatString(color, dark));
|
||||
}
|
||||
if (dark) {
|
||||
banner.append("${AnsiBackground.DEFAULT}");
|
||||
}
|
||||
banner.append("${AnsiColor.DEFAULT}\n");
|
||||
}
|
||||
|
||||
return banner.toString();
|
||||
}
|
||||
|
||||
protected String getFormatString(Color color, boolean dark) {
|
||||
String matchedColorName = null;
|
||||
Double minColorDistance = null;
|
||||
|
||||
for (Entry<String, Color> colorOption : this.colors.entrySet()) {
|
||||
double distance = getColorDistance(color, colorOption.getValue());
|
||||
|
||||
if (minColorDistance == null || distance < minColorDistance) {
|
||||
minColorDistance = distance;
|
||||
matchedColorName = colorOption.getKey();
|
||||
}
|
||||
}
|
||||
|
||||
return "${AnsiColor." + matchedColorName + "}" + getAsciiCharacter(color, dark);
|
||||
}
|
||||
|
||||
private static int getLuminance(Color color, boolean inverse) {
|
||||
double red = color.getRed();
|
||||
double green = color.getGreen();
|
||||
double blue = color.getBlue();
|
||||
|
||||
double luminance;
|
||||
|
||||
if (inverse) {
|
||||
luminance = (RED_WEIGHT * (255.0d - red)) + (GREEN_WEIGHT * (255.0d - green))
|
||||
+ (BLUE_WEIGHT * (255.0d - blue));
|
||||
}
|
||||
else {
|
||||
luminance = (RED_WEIGHT * red) + (GREEN_WEIGHT * green)
|
||||
+ (BLUE_WEIGHT * blue);
|
||||
}
|
||||
|
||||
return (int) Math.ceil((luminance / 255.0d) * 100);
|
||||
}
|
||||
|
||||
private static char getAsciiCharacter(Color color, boolean dark) {
|
||||
double luminance = getLuminance(color, dark);
|
||||
|
||||
if (luminance >= 90) {
|
||||
return ' ';
|
||||
}
|
||||
else if (luminance >= 80) {
|
||||
return '.';
|
||||
}
|
||||
else if (luminance >= 70) {
|
||||
return '*';
|
||||
}
|
||||
else if (luminance >= 60) {
|
||||
return ':';
|
||||
}
|
||||
else if (luminance >= 50) {
|
||||
return 'o';
|
||||
}
|
||||
else if (luminance >= 40) {
|
||||
return '&';
|
||||
}
|
||||
else if (luminance >= 30) {
|
||||
return '8';
|
||||
}
|
||||
else if (luminance >= 20) {
|
||||
return '#';
|
||||
}
|
||||
else {
|
||||
return '@';
|
||||
}
|
||||
}
|
||||
|
||||
private static double getColorDistance(Color color1, Color color2) {
|
||||
double redDelta = (color1.getRed() - color2.getRed()) * RED_WEIGHT;
|
||||
double greenDelta = (color1.getGreen() - color2.getGreen()) * GREEN_WEIGHT;
|
||||
double blueDelta = (color1.getBlue() - color2.getBlue()) * BLUE_WEIGHT;
|
||||
|
||||
return Math.pow(redDelta, 2.0d) + Math.pow(greenDelta, 2.0d)
|
||||
+ Math.pow(blueDelta, 2.0d);
|
||||
}
|
||||
|
||||
private static BufferedImage resizeImage(BufferedImage sourceImage, int maxWidth,
|
||||
double aspectRatio) {
|
||||
int width;
|
||||
double resizeRatio;
|
||||
if (sourceImage.getWidth() > maxWidth) {
|
||||
resizeRatio = (double) maxWidth / (double) sourceImage.getWidth();
|
||||
width = maxWidth;
|
||||
}
|
||||
else {
|
||||
resizeRatio = 1.0d;
|
||||
width = sourceImage.getWidth();
|
||||
}
|
||||
|
||||
int height = (int) (Math.ceil(resizeRatio * aspectRatio
|
||||
* (double) sourceImage.getHeight()));
|
||||
Image image = sourceImage.getScaledInstance(width, height, Image.SCALE_DEFAULT);
|
||||
|
||||
BufferedImage resizedImage = new BufferedImage(image.getWidth(null),
|
||||
image.getHeight(null), BufferedImage.TYPE_INT_RGB);
|
||||
|
||||
resizedImage.getGraphics().drawImage(image, 0, 0, null);
|
||||
return resizedImage;
|
||||
}
|
||||
}
|
|
@ -140,6 +140,7 @@ import org.springframework.web.context.support.StandardServletEnvironment;
|
|||
* @author Christian Dupuis
|
||||
* @author Stephane Nicoll
|
||||
* @author Jeremy Rickard
|
||||
* @author Craig Burke
|
||||
* @see #run(Object, String[])
|
||||
* @see #run(Object[], String[])
|
||||
* @see #SpringApplication(Object...)
|
||||
|
@ -569,9 +570,27 @@ public class SpringApplication {
|
|||
if (this.banner != null) {
|
||||
return this.banner;
|
||||
}
|
||||
|
||||
Resource image = getBannerImage(environment, resourceLoader);
|
||||
if (image.exists()) {
|
||||
return new ImageBanner(image);
|
||||
}
|
||||
|
||||
return DEFAULT_BANNER;
|
||||
}
|
||||
|
||||
private Resource getBannerImage(Environment environment, ResourceLoader resourceLoader) {
|
||||
String imageLocation = environment.getProperty("banner.image", "banner.gif");
|
||||
Resource image = resourceLoader.getResource(imageLocation);
|
||||
if (!image.exists()) {
|
||||
image = resourceLoader.getResource("banner.jpg");
|
||||
}
|
||||
if (!image.exists()) {
|
||||
image = resourceLoader.getResource("banner.png");
|
||||
}
|
||||
return image;
|
||||
}
|
||||
|
||||
private String createStringFromBanner(Banner banner, Environment environment)
|
||||
throws UnsupportedEncodingException {
|
||||
ByteArrayOutputStream baos = new ByteArrayOutputStream();
|
||||
|
|
|
@ -0,0 +1,239 @@
|
|||
/*
|
||||
* Copyright 2012-2014 the original author or authors.
|
||||
*
|
||||
* 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 org.springframework.boot;
|
||||
|
||||
import java.io.ByteArrayOutputStream;
|
||||
import java.io.PrintStream;
|
||||
import java.util.HashMap;
|
||||
import java.util.Map;
|
||||
|
||||
import org.junit.Before;
|
||||
import org.junit.Test;
|
||||
|
||||
import org.springframework.boot.ansi.AnsiBackground;
|
||||
import org.springframework.boot.ansi.AnsiColor;
|
||||
import org.springframework.boot.ansi.AnsiElement;
|
||||
import org.springframework.boot.ansi.AnsiOutput;
|
||||
import org.springframework.core.env.ConfigurableEnvironment;
|
||||
import org.springframework.core.env.MapPropertySource;
|
||||
import org.springframework.core.io.ClassPathResource;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.mock.env.MockEnvironment;
|
||||
|
||||
import static org.hamcrest.Matchers.containsString;
|
||||
import static org.hamcrest.Matchers.equalTo;
|
||||
import static org.hamcrest.Matchers.startsWith;
|
||||
|
||||
import static org.junit.Assert.assertThat;
|
||||
|
||||
/**
|
||||
* Tests for {@link ImageBanner}.
|
||||
*
|
||||
* @author Craig Burke
|
||||
*/
|
||||
public class ImageBannerTests {
|
||||
|
||||
private static final String IMAGE_BANNER_BLACK_AND_WHITE = "banners/black-and-white.gif";
|
||||
private static final String IMAGE_BANNER_LARGE = "banners/large.gif";
|
||||
private static final String IMAGE_BANNER_ALL_COLORS = "banners/colors.gif";
|
||||
private static final String IMAGE_BANNER_GRADIENT = "banners/gradient.gif";
|
||||
|
||||
private static final String BACKGROUND_DEFAULT_ANSI = getAnsiOutput(AnsiBackground.DEFAULT);
|
||||
private static final String BACKGROUND_DARK_ANSI = getAnsiOutput(AnsiBackground.BLACK);
|
||||
|
||||
private static final char HIGH_LUMINANCE_CHARACTER = ' ';
|
||||
private static final char LOW_LUMINANCE_CHARACTER = '@';
|
||||
|
||||
private static Map<String, Object> properties;
|
||||
|
||||
@Before
|
||||
public void setup() {
|
||||
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
|
||||
properties = new HashMap<String, Object>();
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderDefaultBackground() {
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
|
||||
assertThat(banner, startsWith(BACKGROUND_DEFAULT_ANSI));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderDarkBackground() {
|
||||
setDark(true);
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
|
||||
assertThat(banner, startsWith(BACKGROUND_DARK_ANSI));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderWhiteCharactersWithColors() {
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
String expectedFirstLine = getAnsiOutput(AnsiColor.BRIGHT_WHITE)
|
||||
+ HIGH_LUMINANCE_CHARACTER;
|
||||
|
||||
assertThat(banner, containsString(expectedFirstLine));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderWhiteCharactersOnDarkBackground() {
|
||||
setDark(true);
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
String expectedFirstLine = getAnsiOutput(AnsiColor.BRIGHT_WHITE)
|
||||
+ LOW_LUMINANCE_CHARACTER;
|
||||
|
||||
assertThat(banner, containsString(expectedFirstLine));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderBlackCharactersOnDefaultBackground() {
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
String blackCharacter = getAnsiOutput(AnsiColor.BLACK) + LOW_LUMINANCE_CHARACTER;
|
||||
|
||||
assertThat(banner, containsString(blackCharacter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderBlackCharactersOnDarkBackground() {
|
||||
setDark(true);
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
String blackCharacter = getAnsiOutput(AnsiColor.BLACK) + HIGH_LUMINANCE_CHARACTER;
|
||||
|
||||
assertThat(banner, containsString(blackCharacter));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderBannerWithAllColors() {
|
||||
String banner = printBanner(IMAGE_BANNER_ALL_COLORS);
|
||||
|
||||
assertThat("Banner contains BLACK", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BLACK)));
|
||||
assertThat("Banner contains RED", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.RED)));
|
||||
assertThat("Banner contains GREEN", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.GREEN)));
|
||||
assertThat("Banner contains YELLOW", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.YELLOW)));
|
||||
assertThat("Banner contains BLUE", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BLUE)));
|
||||
assertThat("Banner contains MAGENTA", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.MAGENTA)));
|
||||
assertThat("Banner contains CYAN", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.CYAN)));
|
||||
assertThat("Banner contains WHITE", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.WHITE)));
|
||||
|
||||
assertThat("Banner contains BRIGHT_BLACK", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_BLACK)));
|
||||
assertThat("Banner contains BRIGHT_RED", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_RED)));
|
||||
assertThat("Banner contains BRIGHT_GREEN", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_GREEN)));
|
||||
assertThat("Banner contains BRIGHT_YELLOW", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_YELLOW)));
|
||||
assertThat("Banner contains BRIGHT_BLUE", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_BLUE)));
|
||||
assertThat("Banner contains BRIGHT_MAGENTA", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_MAGENTA)));
|
||||
assertThat("Banner contains BRIGHT_CYAN", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_CYAN)));
|
||||
assertThat("Banner contains BRIGHT_WHITE", banner,
|
||||
containsString(getAnsiOutput(AnsiColor.BRIGHT_WHITE)));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderSimpleGradient() {
|
||||
AnsiOutput.setEnabled(AnsiOutput.Enabled.NEVER);
|
||||
String banner = printBanner(IMAGE_BANNER_GRADIENT);
|
||||
String expectedResult = "@#8&o:*. ";
|
||||
|
||||
assertThat(banner, startsWith(expectedResult));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderBannerWithDefaultAspectRatio() {
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
int bannerHeight = getBannerHeight(banner);
|
||||
|
||||
assertThat(bannerHeight, equalTo(2));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderBannerWithCustomAspectRatio() {
|
||||
setAspectRatio(1.0d);
|
||||
String banner = printBanner(IMAGE_BANNER_BLACK_AND_WHITE);
|
||||
int bannerHeight = getBannerHeight(banner);
|
||||
|
||||
assertThat(bannerHeight, equalTo(4));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderLargeBanner() {
|
||||
String banner = printBanner(IMAGE_BANNER_LARGE);
|
||||
int bannerWidth = getBannerWidth(banner);
|
||||
|
||||
assertThat(bannerWidth, equalTo(72));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void renderLargeBannerWithACustomWidth() {
|
||||
setMaxWidth(60);
|
||||
String banner = printBanner(IMAGE_BANNER_LARGE);
|
||||
int bannerWidth = getBannerWidth(banner);
|
||||
|
||||
assertThat(bannerWidth, equalTo(60));
|
||||
}
|
||||
|
||||
private int getBannerHeight(String banner) {
|
||||
return banner.split("\n").length;
|
||||
}
|
||||
|
||||
private int getBannerWidth(String banner) {
|
||||
String strippedBanner = banner.replaceAll("\u001B\\[.*?m", "");
|
||||
String firstLine = strippedBanner.split("\n")[0];
|
||||
return firstLine.length();
|
||||
}
|
||||
|
||||
private static String getAnsiOutput(AnsiElement ansi) {
|
||||
return "\u001B[" + ansi.toString() + "m";
|
||||
}
|
||||
|
||||
private void setDark(boolean dark) {
|
||||
properties.put("banner.image.dark", dark);
|
||||
}
|
||||
|
||||
private void setMaxWidth(int maxWidth) {
|
||||
properties.put("banner.image.max-width", maxWidth);
|
||||
}
|
||||
|
||||
private void setAspectRatio(double aspectRatio) {
|
||||
properties.put("banner.image.aspect-ratio", aspectRatio);
|
||||
}
|
||||
|
||||
private String printBanner(String imagePath) {
|
||||
Resource image = new ClassPathResource(imagePath);
|
||||
ImageBanner banner = new ImageBanner(image);
|
||||
ConfigurableEnvironment environment = new MockEnvironment();
|
||||
environment.getPropertySources().addLast(
|
||||
new MapPropertySource("testConfig", properties));
|
||||
ByteArrayOutputStream out = new ByteArrayOutputStream();
|
||||
banner.printBanner(environment, getClass(), new PrintStream(out));
|
||||
return out.toString();
|
||||
}
|
||||
|
||||
}
|
|
@ -19,8 +19,10 @@ package org.springframework.boot;
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.Collections;
|
||||
import java.util.HashMap;
|
||||
import java.util.LinkedHashSet;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.Set;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
|
@ -66,6 +68,7 @@ import org.springframework.core.env.MapPropertySource;
|
|||
import org.springframework.core.env.PropertySource;
|
||||
import org.springframework.core.env.StandardEnvironment;
|
||||
import org.springframework.core.io.DefaultResourceLoader;
|
||||
import org.springframework.core.io.Resource;
|
||||
import org.springframework.core.io.ResourceLoader;
|
||||
import org.springframework.test.context.support.TestPropertySourceUtils;
|
||||
import org.springframework.util.StringUtils;
|
||||
|
@ -90,6 +93,7 @@ import static org.mockito.Mockito.verify;
|
|||
* @author Christian Dupuis
|
||||
* @author Stephane Nicoll
|
||||
* @author Jeremy Rickard
|
||||
* @author Craig Burke
|
||||
*/
|
||||
public class SpringApplicationTests {
|
||||
|
||||
|
@ -191,6 +195,32 @@ public class SpringApplicationTests {
|
|||
.startsWith(String.format("Running a Test!%n%n123456"));
|
||||
}
|
||||
|
||||
@Test
|
||||
public void textBannerTakesPrecedence() throws Exception {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
BannerResourceLoaderStub resourceLoader = new BannerResourceLoaderStub();
|
||||
resourceLoader.addResource("banner.gif", "banners/black-and-white.gif");
|
||||
resourceLoader.addResource("banner.txt", "banners/foobar.txt");
|
||||
|
||||
application.setWebEnvironment(false);
|
||||
application.setResourceLoader(resourceLoader);
|
||||
application.run();
|
||||
|
||||
assertThat(this.output.toString()).startsWith("Foo Bar");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void imageBannerLoads() throws Exception {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
BannerResourceLoaderStub resourceLoader = new BannerResourceLoaderStub();
|
||||
resourceLoader.addResource("banner.gif", "banners/black-and-white.gif");
|
||||
application.setWebEnvironment(false);
|
||||
application.setResourceLoader(resourceLoader);
|
||||
application.run();
|
||||
|
||||
assertThat(this.output.toString()).startsWith("@");
|
||||
}
|
||||
|
||||
@Test
|
||||
public void logsNoActiveProfiles() throws Exception {
|
||||
SpringApplication application = new SpringApplication(ExampleConfig.class);
|
||||
|
@ -1089,4 +1119,31 @@ public class SpringApplicationTests {
|
|||
}
|
||||
|
||||
}
|
||||
|
||||
private static class BannerResourceLoaderStub extends DefaultResourceLoader {
|
||||
|
||||
private Map<String, String> resources = new HashMap<String, String>();
|
||||
Resource notFoundResource;
|
||||
|
||||
BannerResourceLoaderStub() {
|
||||
this.notFoundResource = super.getResource("classpath:foo/bar/foobar");
|
||||
assert !this.notFoundResource.exists();
|
||||
}
|
||||
|
||||
public void addResource(String file, String realPath) {
|
||||
this.resources.put(file, realPath);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Resource getResource(String s) {
|
||||
if (this.resources.containsKey(s)) {
|
||||
return super.getResource("classpath:" + this.resources.get(s));
|
||||
}
|
||||
else {
|
||||
return this.notFoundResource;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Binary file not shown.
After Width: | Height: | Size: 44 B |
Binary file not shown.
After Width: | Height: | Size: 95 B |
|
@ -0,0 +1 @@
|
|||
Foo Bar
|
Binary file not shown.
After Width: | Height: | Size: 817 B |
Binary file not shown.
After Width: | Height: | Size: 142 B |
Loading…
Reference in New Issue