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.*;
022
023/**
024 * Tri-state result of a property lookup.
025 *
026 * <p>
027 * This type disambiguates source lookup semantics:
028 * <ul class='spaced-list'>
029 *    <li>{@link #missing()} - The key does not exist in the source.
030 *    <li>{@link #present(Optional)} with {@link Optional#empty()} - The key exists and resolves to a null value.
031 *    <li>{@link #present(Optional)} with a value - The key exists and resolves to a non-null value.
032 * </ul>
033 */
034public final class PropertyLookupResult {
035
036   private static final PropertyLookupResult MISSING = new PropertyLookupResult(false, oe());
037
038   private final boolean present;
039   private final Optional<String> value;
040
041   private PropertyLookupResult(boolean present, Optional<String> value) {
042      this.present = present;
043      this.value = value;
044   }
045
046   /**
047    * Returns a result indicating the key is absent in this source.
048    *
049    * @return A missing result.
050    */
051   public static PropertyLookupResult missing() {
052      return MISSING;
053   }
054
055   /**
056    * Returns a result indicating the key is present with the specified value.
057    *
058    * @param value The value optional. Must not be <jk>null</jk>.
059    * @return A present result.
060    */
061   public static PropertyLookupResult present(Optional<String> value) {
062      return new PropertyLookupResult(true, Objects.requireNonNull(value));
063   }
064
065   /**
066    * Returns a result indicating the key is present with the specified value.
067    *
068    * @param value The value.  Can be <jk>null</jk>, in which case the result is present with an empty value.
069    * @return A present result.
070    */
071   public static PropertyLookupResult present(String value) {
072      return present(o(value));
073   }
074
075   /**
076    * Returns <jk>true</jk> if the key is present in this source.
077    *
078    * @return <jk>true</jk> if present.
079    */
080   public boolean isPresent() {
081      return present;
082   }
083
084   /**
085    * Returns the resolved value for present results.
086    *
087    * @return The value, never <jk>null</jk>.
088    */
089   public Optional<String> value() {
090      return value;
091   }
092}