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.lang; 018 019import static org.apache.juneau.commons.utils.AssertionUtils.*; 020import static org.apache.juneau.commons.utils.Utils.*; 021 022/** 023 * A simple mutable string value. 024 * 025 * <p> 026 * This class extends {@link Value}<{@link String}> and adds convenience methods for string 027 * equality testing, which are useful in lambdas and conditional logic. 028 * 029 * <h5 class='section'>Notes:</h5><ul> 030 * <li class='note'> 031 * This class is <b>not thread-safe</b>. For concurrent access, use synchronization or atomic classes. 032 * </ul> 033 * 034 * <h5 class='section'>Example:</h5> 035 * <p class='bjava'> 036 * <jc>// Create a mutable string</jc> 037 * StringValue <jv>name</jv> = StringValue.<jsm>of</jsm>(<js>"John"</js>); 038 * 039 * <jc>// Check equality</jc> 040 * <jk>if</jk> (<jv>name</jv>.is(<js>"John"</js>)) { 041 * <jsm>System</jsm>.<jsf>out</jsf>.println(<js>"Name is John"</js>); 042 * } 043 * 044 * <jc>// Check multiple values</jc> 045 * <jk>if</jk> (<jv>name</jv>.isAny(<js>"John"</js>, <js>"Jane"</js>, <js>"Bob"</js>)) { 046 * <jsm>System</jsm>.<jsf>out</jsf>.println(<js>"Name found"</js>); 047 * } 048 * </p> 049 * 050 * <h5 class='section'>See Also:</h5><ul> 051 * <li class='link'><a class="doclink" href="https://juneau.apache.org/docs/topics/JuneauCommonsLang">Lang Package</a> 052 * </ul> 053 */ 054public class StringValue extends Value<String> { 055 056 /** 057 * Creates a new empty string value. 058 * 059 * <h5 class='section'>Example:</h5> 060 * <p class='bjava'> 061 * StringValue <jv>name</jv> = StringValue.<jsm>create</jsm>(); 062 * <jsm>assertNull</jsm>(<jv>name</jv>.get()); 063 * </p> 064 * 065 * @return A new string value. 066 */ 067 public static StringValue create() { 068 return of(null); 069 } 070 071 /** 072 * Creates a new string value with the specified initial value. 073 * 074 * <h5 class='section'>Example:</h5> 075 * <p class='bjava'> 076 * StringValue <jv>name</jv> = StringValue.<jsm>of</jsm>(<js>"Hello"</js>); 077 * <jsm>assertEquals</jsm>(<js>"Hello"</js>, <jv>name</jv>.get()); 078 * </p> 079 * 080 * @param value The initial value. 081 * @return A new string value. 082 */ 083 public static StringValue of(String value) { 084 return new StringValue(value); 085 } 086 087 /** 088 * Constructor. 089 */ 090 public StringValue() { 091 super(null); 092 } 093 094 /** 095 * Constructor. 096 * 097 * @param value The initial value. 098 */ 099 public StringValue(String value) { 100 super(value); 101 } 102 103 /** 104 * Checks if the current value is equal to the specified value. 105 * 106 * <p> 107 * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison, which handles nulls safely. 108 * 109 * <h5 class='section'>Example:</h5> 110 * <p class='bjava'> 111 * StringValue <jv>name</jv> = StringValue.<jsm>of</jsm>(<js>"John"</js>); 112 * <jsm>assertTrue</jsm>(<jv>name</jv>.is(<js>"John"</js>)); 113 * <jsm>assertFalse</jsm>(<jv>name</jv>.is(<js>"Jane"</js>)); 114 * 115 * <jc>// Handles null safely</jc> 116 * StringValue <jv>empty</jv> = StringValue.<jsm>create</jsm>(); 117 * <jsm>assertTrue</jsm>(<jv>empty</jv>.is(<jk>null</jk>)); 118 * </p> 119 * 120 * @param value The value to compare to. 121 * @return <jk>true</jk> if the current value is equal to the specified value. 122 */ 123 public boolean is(String value) { 124 return eq(get(), value); 125 } 126 127 /** 128 * Checks if the current value matches any of the specified values. 129 * 130 * <p> 131 * Uses {@link org.apache.juneau.commons.utils.Utils#eq(Object, Object)} for deep equality comparison of each value. 132 * 133 * <h5 class='section'>Example:</h5> 134 * <p class='bjava'> 135 * StringValue <jv>name</jv> = StringValue.<jsm>of</jsm>(<js>"John"</js>); 136 * <jsm>assertTrue</jsm>(<jv>name</jv>.isAny(<js>"John"</js>, <js>"Jane"</js>, <js>"Bob"</js>)); 137 * <jsm>assertFalse</jsm>(<jv>name</jv>.isAny(<js>"Alice"</js>, <js>"Charlie"</js>)); 138 * 139 * <jc>// Empty array returns false</jc> 140 * <jsm>assertFalse</jsm>(<jv>name</jv>.isAny()); 141 * </p> 142 * 143 * @param values The values to compare to. 144 * @return <jk>true</jk> if the current value matches any of the specified values. 145 */ 146 public boolean isAny(String...values) { 147 assertArgNotNull("values", values); 148 var current = get(); 149 for (var value : values) 150 if (eq(current, value)) 151 return true; 152 return false; 153 } 154}