001// *************************************************************************************************************************** 002// * Licensed to the Apache Software Foundation (ASF) under one or more contributor license agreements. See the NOTICE file * 003// * distributed with this work for additional information regarding copyright ownership. The ASF licenses this file * 004// * to you under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance * 005// * with the License. You may obtain a copy of the License at * 006// * * 007// * http://www.apache.org/licenses/LICENSE-2.0 * 008// * * 009// * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an * 010// * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the * 011// * specific language governing permissions and limitations under the License. * 012// *************************************************************************************************************************** 013package org.apache.juneau; 014 015import java.lang.reflect.*; 016 017import org.apache.juneau.reflect.*; 018 019/** 020 * Represents a simple settable value. 021 * 022 * <p> 023 * This object is not thread safe. 024 * 025 * @param <T> The value type. 026 */ 027public class Value<T> { 028 029 /** 030 * Returns the generic parameter type of the Value parameter at the specified position. 031 * 032 * <h5 class='figure'>Example:</h5> 033 * <p class='bcode w800'> 034 * <jk>public class</jk> A { 035 * <jk>public void</jk> doX(Value<Foo> foo) {...} 036 * } 037 * </p> 038 * <p class='bcode w800'> 039 * Class<?> t = Value.<jsm>getValueType</jsm>(A.<jk>class</jk>.getMethod(<js>"doX"</js>, Value.<jk>class</jk>)); 040 * <jsm>assertTrue</jsm>(t == Foo.<jk>class</jk>); 041 * </p> 042 * 043 * @param m The method containing the parameter. 044 * @param i The index of the parameter. 045 * @return The parameter type of the value, or <jk>null</jk> if the method parameter is not of type <c>Value</c>. 046 */ 047 public static Type getParameterType(Method m, int i) { 048 return getParameterType(m.getGenericParameterTypes()[i]); 049 } 050 051 /** 052 * Returns the generic parameter type of the Value type. 053 * 054 * @param t The type to find the parameter type of. 055 * @return The parameter type of the value, or <jk>null</jk> if the type is not a subclass of <c>Value</c>. 056 */ 057 public static Type getParameterType(Type t) { 058 if (t instanceof ParameterizedType) { 059 ParameterizedType pt = (ParameterizedType)t; 060 if (pt.getRawType() == Value.class) { 061 Type[] ta = pt.getActualTypeArguments(); 062 if (ta.length > 0) 063 return ta[0]; 064 } 065 } else if (t instanceof Class) { 066 Class<?> c = (Class<?>)t; 067 if (Value.class.isAssignableFrom(c)) { 068 return ClassInfo.of(c).getParameterType(0, Value.class); 069 } 070 } 071 072 return null; 073 } 074 075 /** 076 * Convenience method for checking if the specified type is this class. 077 * 078 * @param t The type to check. 079 * @return <jk>true</jk> if the specified type is this class. 080 */ 081 public static boolean isType(Type t) { 082 return 083 (t instanceof ParameterizedType && ((ParameterizedType)t).getRawType() == Value.class) 084 || (t instanceof Class && Value.class.isAssignableFrom((Class<?>)t)); 085 } 086 087 private T t; 088 private ValueListener<T> listener; 089 090 /** 091 * Constructor. 092 */ 093 public Value() { 094 } 095 096 /** 097 * Constructor. 098 * 099 * @param t Initial value. 100 */ 101 public Value(T t) { 102 set(t); 103 } 104 105 /** 106 * Adds a listener for this value. 107 * 108 * @param listener The new listener for this value. 109 * @return This object (for method chaining). 110 */ 111 public Value<T> listener(ValueListener<T> listener) { 112 this.listener = listener; 113 return this; 114 } 115 116 /** 117 * Sets the value. 118 * 119 * @param t The new value. 120 * @return This object (for method chaining). 121 */ 122 public Value<T> set(T t) { 123 this.t = t; 124 if (listener != null) 125 listener.onSet(t); 126 return this; 127 } 128 129 /** 130 * Returns the value. 131 * 132 * @return The value, or <jk>null</jk> if it is not set. 133 */ 134 public T get() { 135 return t; 136 } 137 138 /** 139 * Returns <jk>true</jk> if the value is set. 140 * 141 * @return <jk>true</jk> if the value is set. 142 */ 143 public boolean isSet() { 144 return get() != null; 145 } 146}