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.Shorts.*; 020 021import java.util.*; 022import java.util.function.*; 023 024import org.apache.juneau.commons.function.*; 025 026/** 027 * A memoizer that provides convenience methods for type conversion. 028 * 029 * <p> 030 * This class extends {@link Memoizer} to provide methods to convert the string value 031 * to various types, similar to the {@link StringSetting#asInteger()}, {@link StringSetting#asBoolean()}, etc. methods. 032 * 033 * <h5 class='section'>Example:</h5> 034 * <p class='bjava'> 035 * StringSetting <jv>setting</jv> = Settings.<jsf>get</jsf>().setting(<js>"my.property"</js>); 036 * Setting<Integer> <jv>intValue</jv> = <jv>setting</jv>.asInteger(); 037 * Setting<Boolean> <jv>boolValue</jv> = <jv>setting</jv>.asBoolean(); 038 * Setting<Charset> <jv>charset</jv> = <jv>setting</jv>.asCharset(); 039 * 040 * <jc>// Reset the cache to force recomputation</jc> 041 * <jv>setting</jv>.reset(); 042 * </p> 043 * 044 * @param <T> The type of value supplied. 045 */ 046@SuppressWarnings({ 047 "java:S1192" // Duplicated literals (argument/property names) read more clearly inline than as constants 048}) 049public class Setting<T> extends Memoizer<T> { 050 051 private final Settings settings; 052 053 /** 054 * Creates a new Setting from a Settings instance and a Supplier. 055 * 056 * @param settings The Settings instance that created this setting. Must not be <jk>null</jk>. 057 * @param supplier The supplier that provides the value. Must not be <jk>null</jk>. 058 */ 059 public Setting(Settings settings, Supplier<T> supplier) { 060 super(reqnn("supplier", supplier)); 061 this.settings = reqnn("settings", settings); 062 } 063 064 /** 065 * Returns the Settings instance that created this setting. 066 * 067 * @return The Settings instance. 068 */ 069 public Settings getSettings() { 070 return settings; 071 } 072 073 /** 074 * Returns the underlying Optional<T>. 075 * 076 * <p> 077 * <b>Note:</b> The returned {@link Optional} is a snapshot-in-time of the current value. 078 * Resetting this {@link Setting} will not affect the returned {@link Optional} instance. 079 * To get an updated value after resetting, call this method again. 080 * 081 * @return The optional value. 082 */ 083 public Optional<T> asOptional() { 084 return o(get()); 085 } 086 087 /** 088 * If a value is present, applies the provided mapping function to it and returns a Setting describing the result. 089 * 090 * <p> 091 * The returned Setting maintains its own cache, independent of this supplier. 092 * Resetting the mapped supplier does not affect this supplier, and vice versa. 093 * 094 * @param <U> The type of the result of the mapping function. 095 * @param mapper A mapping function to apply to the value, if present. Must not be <jk>null</jk>. 096 * @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. 097 */ 098 @Override 099 public <U> Setting<U> map(Function<? super T,? extends U> mapper) { 100 reqnn("mapper", mapper); 101 return new Setting<>(settings, () -> { 102 T value = get(); 103 return nn(value) ? mapper.apply(value) : null; 104 }); 105 } 106 107 /** 108 * If a value is present, and the value matches the given predicate, returns a Setting describing the value, otherwise returns an empty Setting. 109 * 110 * <p> 111 * The returned Setting maintains its own cache, independent of this supplier. 112 * Resetting the filtered supplier does not affect this supplier, and vice versa. 113 * 114 * @param predicate A predicate to apply to the value, if present. Must not be <jk>null</jk>. 115 * @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. 116 */ 117 @Override 118 public Setting<T> filter(Predicate<? super T> predicate) { 119 reqnn("predicate", predicate); 120 return new Setting<>(settings, () -> { 121 T value = get(); 122 return (nn(value) && predicate.test(value)) ? value : null; 123 }); 124 } 125} 126