001/* 002 * Copyright 2012-2017 the original author or authors. 003 * 004 * Licensed under the Apache License, Version 2.0 (the "License"); 005 * you may not use this file except in compliance with the License. 006 * You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software 011 * distributed under the License is distributed on an "AS IS" BASIS, 012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 013 * See the License for the specific language governing permissions and 014 * limitations under the License. 015 */ 016 017package org.springframework.boot.ansi; 018 019import java.util.ArrayList; 020import java.util.Collections; 021import java.util.EnumSet; 022import java.util.List; 023import java.util.Set; 024 025import org.springframework.core.env.PropertyResolver; 026import org.springframework.core.env.PropertySource; 027import org.springframework.util.StringUtils; 028 029/** 030 * {@link PropertyResolver} for {@link AnsiStyle}, {@link AnsiColor} and 031 * {@link AnsiBackground} elements. Supports properties of the form 032 * {@code AnsiStyle.BOLD}, {@code AnsiColor.RED} or {@code AnsiBackground.GREEN}. Also 033 * supports a prefix of {@code Ansi.} which is an aggregation of everything (with 034 * background colors prefixed {@code BG_}). 035 * 036 * @author Phillip Webb 037 * @since 1.3.0 038 */ 039public class AnsiPropertySource extends PropertySource<AnsiElement> { 040 041 private static final Iterable<MappedEnum<?>> MAPPED_ENUMS; 042 043 static { 044 List<MappedEnum<?>> enums = new ArrayList<>(); 045 enums.add(new MappedEnum<>("AnsiStyle.", AnsiStyle.class)); 046 enums.add(new MappedEnum<>("AnsiColor.", AnsiColor.class)); 047 enums.add(new MappedEnum<>("AnsiBackground.", AnsiBackground.class)); 048 enums.add(new MappedEnum<>("Ansi.", AnsiStyle.class)); 049 enums.add(new MappedEnum<>("Ansi.", AnsiColor.class)); 050 enums.add(new MappedEnum<>("Ansi.BG_", AnsiBackground.class)); 051 MAPPED_ENUMS = Collections.unmodifiableList(enums); 052 } 053 054 private final boolean encode; 055 056 /** 057 * Create a new {@link AnsiPropertySource} instance. 058 * @param name the name of the property source 059 * @param encode if the output should be encoded 060 */ 061 public AnsiPropertySource(String name, boolean encode) { 062 super(name); 063 this.encode = encode; 064 } 065 066 @Override 067 public Object getProperty(String name) { 068 if (StringUtils.hasLength(name)) { 069 for (MappedEnum<?> mappedEnum : MAPPED_ENUMS) { 070 if (name.startsWith(mappedEnum.getPrefix())) { 071 String enumName = name.substring(mappedEnum.getPrefix().length()); 072 for (Enum<?> ansiEnum : mappedEnum.getEnums()) { 073 if (ansiEnum.name().equals(enumName)) { 074 if (this.encode) { 075 return AnsiOutput.encode((AnsiElement) ansiEnum); 076 } 077 return ansiEnum; 078 } 079 } 080 } 081 } 082 } 083 return null; 084 } 085 086 /** 087 * Mapping between an enum and the pseudo property source. 088 */ 089 private static class MappedEnum<E extends Enum<E>> { 090 091 private final String prefix; 092 093 private final Set<E> enums; 094 095 MappedEnum(String prefix, Class<E> enumType) { 096 this.prefix = prefix; 097 this.enums = EnumSet.allOf(enumType); 098 099 } 100 101 public String getPrefix() { 102 return this.prefix; 103 } 104 105 public Set<E> getEnums() { 106 return this.enums; 107 } 108 109 } 110 111}