001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2022 microBean™. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); 006 * you may not use this file except in compliance with the License. 007 * 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 014 * implied. See the License for the specific language governing 015 * permissions and limitations under the License. 016 */ 017package org.microbean.qualifier; 018 019import java.util.Map; 020 021import java.lang.constant.MethodHandleDesc; 022import java.lang.constant.MethodTypeDesc; 023 024import static java.lang.constant.ConstantDescs.CD_Map; 025import static java.lang.constant.ConstantDescs.CD_Object; 026import static java.lang.constant.ConstantDescs.CD_String; 027 028import static java.lang.constant.DirectMethodHandleDesc.Kind.STATIC; 029 030import static org.microbean.qualifier.ConstantDescs.CD_Qualifier; 031 032/** 033 * A {@link Binding} used to qualify objects. 034 * 035 * <p>This is a <a 036 * href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/doc-files/ValueBased.html">value-based</a> 037 * class.</p> 038 * 039 * @param <V> the type of a {@link Qualifier}'s {@linkplain #value() 040 * value} and of its {@linkplain #attributes() attribute values} 041 * 042 * @author <a href="https://about.me/lairdnelson" 043 * target="_parent">Laird Nelson</a> 044 * 045 * @see Binding 046 */ 047public final class Qualifier<V> extends Binding<V, Qualifier<V>> { 048 049 050 /* 051 * Constructors. 052 */ 053 054 055 /** 056 * Creates a new {@link Qualifier}. 057 * 058 * @param name the name; must not be {@code null} 059 * 060 * @param value the value; may be {@code null} 061 * 062 * @param attributes further describing this {@link Qualifier}; may 063 * be {@code null} 064 * 065 * @param info informational attributes further describing this 066 * {@link Qualifier} that are not considered by its {@link 067 * #equals(Object)} implementation; may be {@code null} 068 * 069 * @see #name() 070 * 071 * @see #value() 072 * 073 * @see #attributes() 074 * 075 * @see #info() 076 * 077 * @see Binding#Binding(String, Object, Map, Map) 078 */ 079 private Qualifier(final String name, 080 final V value, 081 final Map<? extends String, ?> attributes, 082 final Map<? extends String, ?> info) { 083 super(name, value, attributes, info); 084 } 085 086 087 /* 088 * Instance methods. 089 */ 090 091 092 /** 093 * Returns a {@link MethodHandleDesc} describing the constructor or 094 * {@code static} method that will be used to create a <a 095 * href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/invoke/package-summary.html#condycon">dynamic 096 * constant</a> representing this {@link Qualifier}. 097 * 098 * <p>End users have no need to call this method.</p> 099 * 100 * @return a {@link MethodHandleDesc} describing the constructor or 101 * {@code static} method that will be used to create a <a 102 * href="https://docs.oracle.com/en/java/javase/17/docs/api/java.base/java/lang/invoke/package-summary.html#condycon">dynamic 103 * constant</a> representing this {@link Qualifier} 104 * 105 * @nullability This method does not return {@code null}. 106 * 107 * @idempotency This method is idempotent and deterministic. 108 * 109 * @threadsafety This method is safe for concurrent use by multiple 110 * threads. 111 */ 112 @Override // Binding<V, Qualifier<V>> 113 protected final MethodHandleDesc describeConstructor() { 114 return 115 MethodHandleDesc.ofMethod(STATIC, 116 CD_Qualifier, 117 "of", 118 MethodTypeDesc.of(CD_Qualifier, CD_String, CD_Object, CD_Map, CD_Map)); 119 } 120 121 122 /* 123 * Static methods. 124 */ 125 126 127 /** 128 * Returns a {@link Qualifier}, which may or may not be newly 129 * created, representing the supplied arguments. 130 * 131 * @param <V> the type of the {@link Qualifier}'s {@linkplain #value() 132 * value} and of its {@linkplain #attributes() attribute values} 133 * 134 * @param name the {@link Qualifier}'s {@linkplain Qualifier#name() 135 * name}; must not be {@code null} 136 * 137 * @return a {@link Qualifier} 138 * 139 * @nullability This method never returns {@code null}. 140 * 141 * @idempotency This method is idempotent and deterministic. 142 * 143 * @threadsafety This method is safe for concurrent use by multiple 144 * threads. 145 */ 146 public static final <V> Qualifier<V> of(final String name) { 147 return of(name, null, null, null); 148 } 149 150 /** 151 * Returns a {@link Qualifier}, which may or may not be newly 152 * created, representing the supplied arguments. 153 * 154 * @param <V> the type of the {@link Qualifier}'s {@linkplain #value() 155 * value} and of its {@linkplain #attributes() attribute values} 156 * 157 * @param name the {@link Qualifier}'s {@linkplain Qualifier#name() 158 * name}; must not be {@code null} 159 * 160 * @param value the {@link Qualifier}'s {@linkplain 161 * Qualifier#value() value}; may be {@code null} 162 * 163 * @return a {@link Qualifier} 164 * 165 * @nullability This method never returns {@code null}. 166 * 167 * @idempotency This method is idempotent and deterministic. 168 * 169 * @threadsafety This method is safe for concurrent use by multiple 170 * threads. 171 */ 172 public static final <V> Qualifier<V> of(final String name, final V value) { 173 return of(name, value, null, null); 174 } 175 176 /** 177 * Returns a {@link Qualifier}, which may or may not be newly 178 * created, representing the supplied arguments. 179 * 180 * @param <V> the type of the {@link Qualifier}'s {@linkplain #value() 181 * value} and of its {@linkplain #attributes() attribute values} 182 * 183 * @param name the {@link Qualifier}'s {@linkplain Qualifier#name() 184 * name}; must not be {@code null} 185 * 186 * @param value the {@link Qualifier}'s {@linkplain 187 * Qualifier#value() value}; may be {@code null} 188 * 189 * @param attributes the {@link Qualifier}'s {@linkplain 190 * Qualifier#attributes() attributes}; may be {@code null} 191 * 192 * @return a {@link Qualifier} 193 * 194 * @nullability This method never returns {@code null}. 195 * 196 * @idempotency This method is idempotent and deterministic. 197 * 198 * @threadsafety This method is safe for concurrent use by multiple 199 * threads. 200 */ 201 public static final <V> Qualifier<V> of(final String name, 202 final V value, 203 final Map<? extends String, ?> attributes) { 204 return of(name, value, attributes, null); 205 } 206 207 /** 208 * Returns a {@link Qualifier}, which may or may not be newly 209 * created, representing the supplied arguments. 210 * 211 * @param <V> the type of the {@link Qualifier}'s {@linkplain #value() 212 * value} and of its {@linkplain #attributes() attribute values} 213 * 214 * @param name the {@link Qualifier}'s {@linkplain Qualifier#name() 215 * name}; must not be {@code null} 216 * 217 * @param value the {@link Qualifier}'s {@linkplain 218 * Qualifier#value() value}; may be {@code null} 219 * 220 * @param attributes the {@link Qualifier}'s {@linkplain 221 * Qualifier#attributes() attributes}; may be {@code null} 222 * 223 * @param info the {@link Qualifier}'s {@linkplain Qualifier#info() 224 * informational attributes}; may be {@code null} 225 * 226 * @return a {@link Qualifier} 227 * 228 * @nullability This method never returns {@code null}. 229 * 230 * @idempotency This method is idempotent and deterministic. 231 * 232 * @threadsafety This method is safe for concurrent use by multiple 233 * threads. 234 */ 235 public static final <V> Qualifier<V> of(final String name, 236 final V value, 237 final Map<? extends String, ?> attributes, 238 final Map<? extends String, ?> info) { 239 return new Qualifier<>(name, value, attributes, info); 240 } 241 242}