Skip to content
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

import org.springframework.boot.ansi.Ansi256PropertySource;
import org.springframework.boot.ansi.AnsiPropertySource;
import org.springframework.core.env.Environment;
import org.springframework.core.env.MapPropertySource;
Expand All @@ -43,6 +44,7 @@
*
* @author Phillip Webb
* @author Vedran Pavic
* @author Toshiaki Maki
* @since 1.2.0
*/
public class ResourceBanner implements Banner {
Expand Down Expand Up @@ -80,6 +82,7 @@ protected List<PropertyResolver> getPropertyResolvers(Environment environment, C
resolvers.add(environment);
resolvers.add(getVersionResolver(sourceClass));
resolvers.add(getAnsiResolver());
resolvers.add(getAnsi256Resolver());
resolvers.add(getTitleResolver(sourceClass));
return resolvers;
}
Expand Down Expand Up @@ -123,6 +126,12 @@ private PropertyResolver getAnsiResolver() {
return new PropertySourcesPropertyResolver(sources);
}

private PropertyResolver getAnsi256Resolver() {
MutablePropertySources sources = new MutablePropertySources();
sources.addFirst(new Ansi256PropertySource("ansi256"));
return new PropertySourcesPropertyResolver(sources);
}

private PropertyResolver getTitleResolver(Class<?> sourceClass) {
MutablePropertySources sources = new MutablePropertySources();
String applicationTitle = getApplicationTitle(sourceClass);
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,84 @@
/*
* Copyright 2012-2019 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
*
* https://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.ansi;

/**
* {@link AnsiElement} implementation for Ansi 256 colors.
* <p>
* use {@link Ansi256Color.Foreground} or {@link Ansi256Color.Background} as a concrete
* class.
*
* @author Toshiaki Maki
* @since 2.2.0
*/
public abstract class Ansi256Color implements AnsiElement {

/**
* color code
*/
final int colorCode;

/**
* @param colorCode color code (must be 0-255)
* @throws IllegalArgumentException if color code is not between 0 and 255.
*/
Ansi256Color(int colorCode) {
if (colorCode < 0 || colorCode > 255) {
throw new IllegalArgumentException("'colorCode' must be between 0 and 255.");
}
this.colorCode = colorCode;
}

/**
* {@link Ansi256Color} foreground colors.
*
* @author Toshiaki Maki
* @since 2.2.0
*/
public static class Foreground extends Ansi256Color {

public Foreground(int colorCode) {
super(colorCode);
}

@Override
public String toString() {
return "38;5;" + super.colorCode;
}

}

/**
* {@link Ansi256Color} background colors.
*
* @author Toshiaki Maki
* @since 2.2.0
*/
public static class Background extends Ansi256Color {

public Background(int colorCode) {
super(colorCode);
}

@Override
public String toString() {
return "48;5;" + super.colorCode;
}

}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
/*
* Copyright 2012-2019 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
*
* https://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.ansi;

import org.springframework.core.env.PropertyResolver;
import org.springframework.core.env.PropertySource;
import org.springframework.util.StringUtils;

/**
* {@link PropertyResolver} for {@link Ansi256Color.Background} and
* {@link Ansi256Color.Foreground} elements. Supports properties of the form
* {@code Ansi256Color.Foreground_N} and {@code Ansi256Color.Background_N} ({@code N} must
* be between 0 and 255).
*
* @author Toshiaki Maki
* @since 2.2.0
*/
public class Ansi256PropertySource extends PropertySource<AnsiElement> {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I wonder if it would be better to roll this into the existing AnsiPropertySource class?


private static final String PREFIX = "Ansi256Color.";

private static final String FOREGROUND_PREFIX = PREFIX + "Foreground_";

private static final String BACKGROUND_PREFIX = PREFIX + "Background_";

/**
* Create a new {@link Ansi256PropertySource} instance.
* @param name the name of the property source
*/
public Ansi256PropertySource(String name) {
super(name);
}

@Override
public Object getProperty(String name) {
if (StringUtils.hasLength(name)) {
if (name.startsWith(FOREGROUND_PREFIX)) {
final int colorCode = Integer.parseInt(name.substring(FOREGROUND_PREFIX.length()));
return AnsiOutput.encode(new Ansi256Color.Foreground(colorCode));
}
else if (name.startsWith(BACKGROUND_PREFIX)) {
final int colorCode = Integer.parseInt(name.substring(BACKGROUND_PREFIX.length()));
return AnsiOutput.encode(new Ansi256Color.Background(colorCode));
}
}
return null;
}

}
Original file line number Diff line number Diff line change
Expand Up @@ -39,6 +39,7 @@
*
* @author Phillip Webb
* @author Vedran Pavic
* @author Toshiaki Maki
*/
class ResourceBannerTests {

Expand Down Expand Up @@ -95,6 +96,24 @@ void renderWithColorsButDisabled() {
assertThat(banner).startsWith("This is red.");
}

@Test
void renderWith256Colors() {
Resource resource = new ByteArrayResource(
"${Ansi256Color.Foreground_208}This is orange.${Ansi.NORMAL}".getBytes());
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
String banner = printBanner(resource, null, null, null);
assertThat(banner).startsWith("\033[38;5;208mThis is orange.\u001B[0m");
}

@Test
void renderWith256ColorsButDisabled() {
Resource resource = new ByteArrayResource(
"${Ansi256Color.Foreground_208}This is orange.${Ansi.NORMAL}".getBytes());
AnsiOutput.setEnabled(AnsiOutput.Enabled.NEVER);
String banner = printBanner(resource, null, null, null);
assertThat(banner).startsWith("This is orange.");
}

@Test
void renderWithTitle() {
Resource resource = new ByteArrayResource("banner ${application.title} ${a}".getBytes());
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright 2012-2019 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
*
* https://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.ansi;

import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.failBecauseExceptionWasNotThrown;

/**
* Tests for {@link Ansi256Color}.
*
* @author Toshiaki Maki
*/
class Ansi256ColorTest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be named Ansi256ColorTests


@Test
void testForeground() {
final Ansi256Color ansi256Color = new Ansi256Color.Foreground(208);
assertThat(ansi256Color.toString()).isEqualTo("38;5;208");
}

@Test
void testBackground() {
final Ansi256Color ansi256Color = new Ansi256Color.Background(208);
assertThat(ansi256Color.toString()).isEqualTo("48;5;208");
}

@Test
void testIllegalColorCode() {
try {
new Ansi256Color.Foreground(256);
failBecauseExceptionWasNotThrown(IllegalArgumentException.class);
}
catch (IllegalArgumentException ex) {
assertThat(ex.getMessage()).isEqualTo("'colorCode' must be between 0 and 255.");
}
}

}
Original file line number Diff line number Diff line change
@@ -0,0 +1,59 @@
/*
* Copyright 2012-2019 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
*
* https://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.ansi;

import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;

import static org.assertj.core.api.Assertions.assertThat;

/**
* Tests for {@link Ansi256PropertySource}.
*
* @author Toshiaki Maki
*/
class Ansi256PropertySourceTest {
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This should be named Ansi256PropertySourceTests


private Ansi256PropertySource source = new Ansi256PropertySource("ansi256");

@AfterEach
void reset() {
AnsiOutput.setEnabled(AnsiOutput.Enabled.DETECT);
}

@Test
void getPropertyShouldConvertAnsi256ColorForeground() {
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
final Object property = this.source.getProperty("Ansi256Color.Foreground_100");
assertThat(property).isEqualTo("\033[38;5;100m");
}

@Test
void getPropertyShouldConvertAnsi256ColorBackground() {
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
final Object property = this.source.getProperty("Ansi256Color.Background_100");
assertThat(property).isEqualTo("\033[48;5;100m");
}

@Test
void getMissingPropertyShouldReturnNull() {
AnsiOutput.setEnabled(AnsiOutput.Enabled.ALWAYS);
final Object property = this.source.getProperty("Ansi256Color.ForeGround_100");
assertThat(property).isNull();
}

}