001/* 002 * Copyright 2012-2018 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.autoconfigure.info; 018 019import java.io.IOException; 020import java.nio.charset.Charset; 021import java.util.Properties; 022 023import org.springframework.boot.autoconfigure.EnableAutoConfiguration; 024import org.springframework.boot.autoconfigure.condition.ConditionMessage; 025import org.springframework.boot.autoconfigure.condition.ConditionOutcome; 026import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean; 027import org.springframework.boot.autoconfigure.condition.ConditionalOnResource; 028import org.springframework.boot.autoconfigure.condition.SpringBootCondition; 029import org.springframework.boot.context.properties.EnableConfigurationProperties; 030import org.springframework.boot.info.BuildProperties; 031import org.springframework.boot.info.GitProperties; 032import org.springframework.context.annotation.Bean; 033import org.springframework.context.annotation.ConditionContext; 034import org.springframework.context.annotation.Conditional; 035import org.springframework.context.annotation.Configuration; 036import org.springframework.core.env.Environment; 037import org.springframework.core.io.DefaultResourceLoader; 038import org.springframework.core.io.Resource; 039import org.springframework.core.io.ResourceLoader; 040import org.springframework.core.io.support.EncodedResource; 041import org.springframework.core.io.support.PropertiesLoaderUtils; 042import org.springframework.core.type.AnnotatedTypeMetadata; 043 044/** 045 * {@link EnableAutoConfiguration Auto-configuration} for various project information. 046 * 047 * @author Stephane Nicoll 048 * @author Madhura Bhave 049 * @since 1.4.0 050 */ 051@Configuration 052@EnableConfigurationProperties(ProjectInfoProperties.class) 053public class ProjectInfoAutoConfiguration { 054 055 private final ProjectInfoProperties properties; 056 057 public ProjectInfoAutoConfiguration(ProjectInfoProperties properties) { 058 this.properties = properties; 059 } 060 061 @Conditional(GitResourceAvailableCondition.class) 062 @ConditionalOnMissingBean 063 @Bean 064 public GitProperties gitProperties() throws Exception { 065 return new GitProperties(loadFrom(this.properties.getGit().getLocation(), "git", 066 this.properties.getGit().getEncoding())); 067 } 068 069 @ConditionalOnResource(resources = "${spring.info.build.location:classpath:META-INF/build-info.properties}") 070 @ConditionalOnMissingBean 071 @Bean 072 public BuildProperties buildProperties() throws Exception { 073 return new BuildProperties(loadFrom(this.properties.getBuild().getLocation(), 074 "build", this.properties.getBuild().getEncoding())); 075 } 076 077 protected Properties loadFrom(Resource location, String prefix, Charset encoding) 078 throws IOException { 079 prefix = prefix.endsWith(".") ? prefix : prefix + "."; 080 Properties source = loadSource(location, encoding); 081 Properties target = new Properties(); 082 for (String key : source.stringPropertyNames()) { 083 if (key.startsWith(prefix)) { 084 target.put(key.substring(prefix.length()), source.get(key)); 085 } 086 } 087 return target; 088 } 089 090 private Properties loadSource(Resource location, Charset encoding) 091 throws IOException { 092 if (encoding != null) { 093 return PropertiesLoaderUtils 094 .loadProperties(new EncodedResource(location, encoding)); 095 } 096 return PropertiesLoaderUtils.loadProperties(location); 097 } 098 099 static class GitResourceAvailableCondition extends SpringBootCondition { 100 101 private final ResourceLoader defaultResourceLoader = new DefaultResourceLoader(); 102 103 @Override 104 public ConditionOutcome getMatchOutcome(ConditionContext context, 105 AnnotatedTypeMetadata metadata) { 106 ResourceLoader loader = context.getResourceLoader(); 107 loader = (loader != null) ? loader : this.defaultResourceLoader; 108 Environment environment = context.getEnvironment(); 109 String location = environment.getProperty("spring.info.git.location"); 110 if (location == null) { 111 location = "classpath:git.properties"; 112 } 113 ConditionMessage.Builder message = ConditionMessage 114 .forCondition("GitResource"); 115 if (loader.getResource(location).exists()) { 116 return ConditionOutcome 117 .match(message.found("git info at").items(location)); 118 } 119 return ConditionOutcome 120 .noMatch(message.didNotFind("git info at").items(location)); 121 } 122 123 } 124 125}