001/* 002 * Copyright 2002-2020 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 * https://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.core.env; 018 019import org.springframework.util.ObjectUtils; 020 021/** 022 * A {@link PropertySource} implementation capable of interrogating its 023 * underlying source object to enumerate all possible property name/value 024 * pairs. Exposes the {@link #getPropertyNames()} method to allow callers 025 * to introspect available properties without having to access the underlying 026 * source object. This also facilitates a more efficient implementation of 027 * {@link #containsProperty(String)}, in that it can call {@link #getPropertyNames()} 028 * and iterate through the returned array rather than attempting a call to 029 * {@link #getProperty(String)} which may be more expensive. Implementations may 030 * consider caching the result of {@link #getPropertyNames()} to fully exploit this 031 * performance opportunity. 032 * 033 * <p>Most framework-provided {@code PropertySource} implementations are enumerable; 034 * a counter-example would be {@code JndiPropertySource} where, due to the 035 * nature of JNDI it is not possible to determine all possible property names at 036 * any given time; rather it is only possible to try to access a property 037 * (via {@link #getProperty(String)}) in order to evaluate whether it is present 038 * or not. 039 * 040 * @author Chris Beams 041 * @author Juergen Hoeller 042 * @since 3.1 043 * @param <T> the source type 044 */ 045public abstract class EnumerablePropertySource<T> extends PropertySource<T> { 046 047 /** 048 * Create a new {@code EnumerablePropertySource} with the given name and source object. 049 * @param name the associated name 050 * @param source the source object 051 */ 052 public EnumerablePropertySource(String name, T source) { 053 super(name, source); 054 } 055 056 /** 057 * Create a new {@code EnumerablePropertySource} with the given name and with a new 058 * {@code Object} instance as the underlying source. 059 * @param name the associated name 060 */ 061 protected EnumerablePropertySource(String name) { 062 super(name); 063 } 064 065 066 /** 067 * Return whether this {@code PropertySource} contains a property with the given name. 068 * <p>This implementation checks for the presence of the given name within the 069 * {@link #getPropertyNames()} array. 070 * @param name the name of the property to find 071 */ 072 @Override 073 public boolean containsProperty(String name) { 074 return ObjectUtils.containsElement(getPropertyNames(), name); 075 } 076 077 /** 078 * Return the names of all properties contained by the 079 * {@linkplain #getSource() source} object (never {@code null}). 080 */ 081 public abstract String[] getPropertyNames(); 082 083}