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.info; 018 019import java.time.Instant; 020import java.util.Iterator; 021import java.util.Map; 022import java.util.Properties; 023 024import org.springframework.core.env.PropertiesPropertySource; 025import org.springframework.core.env.PropertySource; 026import org.springframework.util.Assert; 027 028/** 029 * Base class for components exposing unstructured data with dedicated methods for well 030 * known keys. 031 * 032 * @author Stephane Nicoll 033 * @since 1.4.0 034 */ 035public class InfoProperties implements Iterable<InfoProperties.Entry> { 036 037 private final Properties entries; 038 039 /** 040 * Create an instance with the specified entries. 041 * @param entries the information to expose 042 */ 043 public InfoProperties(Properties entries) { 044 Assert.notNull(entries, "Entries must not be null"); 045 this.entries = copy(entries); 046 } 047 048 /** 049 * Return the value of the specified property or {@code null}. 050 * @param key the key of the property 051 * @return the property value 052 */ 053 public String get(String key) { 054 return this.entries.getProperty(key); 055 } 056 057 /** 058 * Return the value of the specified property as an {@link Instant} or {@code null} if 059 * the value is not a valid {@link Long} representation of an epoch time. 060 * @param key the key of the property 061 * @return the property value 062 */ 063 public Instant getInstant(String key) { 064 String s = get(key); 065 if (s != null) { 066 try { 067 return Instant.ofEpochMilli(Long.parseLong(s)); 068 } 069 catch (NumberFormatException ex) { 070 // Not valid epoch time 071 } 072 } 073 return null; 074 } 075 076 @Override 077 public Iterator<Entry> iterator() { 078 return new PropertiesIterator(this.entries); 079 } 080 081 /** 082 * Return a {@link PropertySource} of this instance. 083 * @return a {@link PropertySource} 084 */ 085 public PropertySource<?> toPropertySource() { 086 return new PropertiesPropertySource(getClass().getSimpleName(), 087 copy(this.entries)); 088 } 089 090 private Properties copy(Properties properties) { 091 Properties copy = new Properties(); 092 copy.putAll(properties); 093 return copy; 094 } 095 096 private final class PropertiesIterator implements Iterator<Entry> { 097 098 private final Iterator<Map.Entry<Object, Object>> iterator; 099 100 private PropertiesIterator(Properties properties) { 101 this.iterator = properties.entrySet().iterator(); 102 } 103 104 @Override 105 public boolean hasNext() { 106 return this.iterator.hasNext(); 107 } 108 109 @Override 110 public Entry next() { 111 Map.Entry<Object, Object> entry = this.iterator.next(); 112 return new Entry((String) entry.getKey(), (String) entry.getValue()); 113 } 114 115 @Override 116 public void remove() { 117 throw new UnsupportedOperationException("InfoProperties are immutable."); 118 } 119 120 } 121 122 /** 123 * Property entry. 124 */ 125 public final class Entry { 126 127 private final String key; 128 129 private final String value; 130 131 private Entry(String key, String value) { 132 this.key = key; 133 this.value = value; 134 } 135 136 public String getKey() { 137 return this.key; 138 } 139 140 public String getValue() { 141 return this.value; 142 } 143 144 } 145 146}