001/* 002 * Licensed to the Apache Software Foundation (ASF) under one or more 003 * contributor license agreements. See the NOTICE file distributed with 004 * this work for additional information regarding copyright ownership. 005 * The ASF licenses this file to You under the Apache License, Version 2.0 006 * (the "License"); you may not use this file except in compliance with 007 * the License. You may obtain a copy of the License at 008 * 009 * http://www.apache.org/licenses/LICENSE-2.0 010 * 011 * Unless required by applicable law or agreed to in writing, software 012 * distributed under the License is distributed on an "AS IS" BASIS, 013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 014 * See the License for the specific language governing permissions and 015 * limitations under the License. 016 */ 017package org.apache.juneau.commons.settings; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020import static org.apache.juneau.commons.utils.Utils.*; 021 022import java.util.Optional; 023import java.util.function.*; 024 025import org.apache.juneau.commons.function.ResettableSupplier; 026 027/** 028 * A resettable supplier that provides convenience methods for type conversion. 029 * 030 * <p> 031 * This class extends {@link ResettableSupplier} to provide methods to convert the string value 032 * to various types, similar to the {@link StringSetting#asInteger()}, {@link StringSetting#asBoolean()}, etc. methods. 033 * 034 * <h5 class='section'>Example:</h5> 035 * <p class='bjava'> 036 * StringSetting <jv>setting</jv> = Settings.<jsf>get</jsf>().setting(<js>"my.property"</js>); 037 * Setting<Integer> <jv>intValue</jv> = <jv>setting</jv>.asInteger(); 038 * Setting<Boolean> <jv>boolValue</jv> = <jv>setting</jv>.asBoolean(); 039 * Setting<Charset> <jv>charset</jv> = <jv>setting</jv>.asCharset(); 040 * 041 * <jc>// Reset the cache to force recomputation</jc> 042 * <jv>setting</jv>.reset(); 043 * </p> 044 * 045 * @param <T> The type of value supplied. 046 */ 047public class Setting<T> extends ResettableSupplier<T> { 048 private final Settings settings; 049 050 /** 051 * Creates a new Setting from a Settings instance and a Supplier. 052 * 053 * @param settings The Settings instance that created this setting. Must not be <jk>null</jk>. 054 * @param supplier The supplier that provides the value. Must not be <jk>null</jk>. 055 */ 056 public Setting(Settings settings, Supplier<T> supplier) { 057 super(assertArgNotNull("supplier", supplier)); 058 this.settings = assertArgNotNull("settings", settings); 059 } 060 061 /** 062 * Returns the Settings instance that created this setting. 063 * 064 * @return The Settings instance. 065 */ 066 public Settings getSettings() { 067 return settings; 068 } 069 070 /** 071 * Returns the underlying Optional<T>. 072 * 073 * <p> 074 * <b>Note:</b> The returned {@link Optional} is a snapshot-in-time of the current value. 075 * Resetting this {@link Setting} will not affect the returned {@link Optional} instance. 076 * To get an updated value after resetting, call this method again. 077 * 078 * @return The optional value. 079 */ 080 public Optional<T> asOptional() { 081 return opt(get()); 082 } 083 084 /** 085 * If a value is present, applies the provided mapping function to it and returns a Setting describing the result. 086 * 087 * <p> 088 * The returned Setting maintains its own cache, independent of this supplier. 089 * Resetting the mapped supplier does not affect this supplier, and vice versa. 090 * 091 * @param <U> The type of the result of the mapping function. 092 * @param mapper A mapping function to apply to the value, if present. Must not be <jk>null</jk>. 093 * @return A Setting describing the result of applying a mapping function to the value of this Setting, if a value is present, otherwise an empty Setting. 094 */ 095 @Override 096 public <U> Setting<U> map(Function<? super T, ? extends U> mapper) { 097 assertArgNotNull("mapper", mapper); 098 return new Setting<>(settings, () -> { 099 T value = get(); 100 return nn(value) ? mapper.apply(value) : null; 101 }); 102 } 103 104 /** 105 * If a value is present, and the value matches the given predicate, returns a Setting describing the value, otherwise returns an empty Setting. 106 * 107 * <p> 108 * The returned Setting maintains its own cache, independent of this supplier. 109 * Resetting the filtered supplier does not affect this supplier, and vice versa. 110 * 111 * @param predicate A predicate to apply to the value, if present. Must not be <jk>null</jk>. 112 * @return A Setting describing the value of this Setting if a value is present and the value matches the given predicate, otherwise an empty Setting. 113 */ 114 @Override 115 public Setting<T> filter(Predicate<? super T> predicate) { 116 assertArgNotNull("predicate", predicate); 117 return new Setting<>(settings, () -> { 118 T value = get(); 119 return (nn(value) && predicate.test(value)) ? value : null; 120 }); 121 } 122} 123