001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*- 002 * 003 * Copyright © 2025 microBean™. 004 * 005 * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with 006 * the License. You may obtain a copy of the License at 007 * 008 * http://www.apache.org/licenses/LICENSE-2.0 009 * 010 * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on 011 * an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the 012 * specific language governing permissions and limitations under the License. 013 */ 014package org.microbean.assign; 015 016import java.util.ArrayList; 017import java.util.Collection; 018import java.util.Collections; 019import java.util.List; 020 021import org.microbean.attributes.Attributes; 022 023/** 024 * A utility class for working with <dfn>qualifiers</dfn>. 025 * 026 * <p>This class is currently not used by other classes in this package. It may be useful in a variety of dependency 027 * injection systems.</p> 028 * 029 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a> 030 * 031 * @see Attributes 032 */ 033public class Qualifiers { 034 035 036 /* 037 * Static fields. 038 */ 039 040 041 private static final Attributes QUALIFIER = Attributes.of("Qualifier"); 042 043 private static final List<Attributes> QUALIFIERS = List.of(QUALIFIER); 044 045 046 /* 047 * Constructors. 048 */ 049 050 051 /** 052 * Creates a new {@link Qualifiers}. 053 */ 054 public Qualifiers() { 055 super(); 056 } 057 058 059 /* 060 * Instance methods. 061 */ 062 063 064 /** 065 * Returns an {@link Attributes} that is {@linkplain Attributes#equals(Object) equal to} the supplied {@link 066 * Attributes}. 067 * 068 * <p>The returned {@link Attributes} may be the supplied {@link Attributes} or a different instance.</p> 069 * 070 * @param a an {@link Attributes}; must not be {@code null} 071 * 072 * @return an {@link Attributes} that is {@linkplain Attributes#equals(Object) equal to} the supplied {@link 073 * Attributes}; never {@code null} 074 * 075 * @exception NullPointerException if {@code a} is {@code null} 076 */ 077 public Attributes normalize(final Attributes a) { 078 return switch (a) { 079 case null -> throw new NullPointerException("a"); 080 case Attributes q when this.qualifier().equals(q) -> this.qualifier(); 081 default -> a; 082 }; 083 } 084 085 /** 086 * Returns an immutable {@link List} of {@link Attributes}s that is {@linkplain List#equals(Object) equal to} the 087 * supplied {@link List}. 088 * 089 * <p>The returned {@link List} may be the supplied {@link List} or a different instance.</p> 090 * 091 * @param list a {@link List} of {@link Attributes}s; must not be {@code null} 092 * 093 * @return an immutable {@link List} of {@link Attributes}s that is {@linkplain List#equals(Object) equal to} the 094 * supplied {@link List}; never {@code null} 095 * 096 * @exception NullPointerException if {@code list} is {@code null} 097 */ 098 public List<Attributes> normalize(final List<Attributes> list) { 099 return switch (list.size()) { 100 case 0 -> List.of(); 101 case 1 -> list.equals(this.qualifiers()) ? this.qualifiers() : List.copyOf(list); 102 default -> { 103 final List<Attributes> l = new ArrayList<>(list.size()); 104 for (final Attributes a : list) { 105 l.add(this.normalize(a)); 106 } 107 yield Collections.unmodifiableList(l); 108 } 109 }; 110 } 111 112 /** 113 * Returns the <dfn>qualifier</dfn> (meta-) qualifier. 114 * 115 * @return the <dfn>qualifier</dfn> (meta-) qualifier; never {@code null} 116 */ 117 public Attributes qualifier() { 118 return QUALIFIER; 119 } 120 121 /** 122 * Returns {@code true} if and only if the supplied {@link Attributes} is an {@link Attributes} that can be used to 123 * designate other {@link Attributes} as qualifiers. 124 * 125 * @param q an {@link Attributes}; must not be {@code null} 126 * 127 * @return {@code true} if and only if the supplied {@link Attributes} is an {@link Attributes} that can be used to 128 * designate other {@link Attributes} as qualifiers 129 * 130 * @exception NullPointerException if {@code q} is {@code null} 131 */ 132 public boolean qualifier(final Attributes q) { 133 return q.attributes().contains(this.qualifier()); 134 } 135 136 /** 137 * Returns an immutable {@link List} consisting solely of the <dfn>qualifier</dfn> (meta-) qualifier. 138 * 139 * @return an immutable {@link List}; never {@code null} 140 * 141 * @see #qualifier() 142 */ 143 public List<Attributes> qualifiers() { 144 return QUALIFIERS; 145 } 146 147 /** 148 * Returns an unmodifiable {@link List} consisting only of those {@link Attributes} in the supplied {@link 149 * Collection} that {@linkplain #qualifier(Attributes) are qualifiers}. 150 * 151 * @param c a {@link Collection} of {@link Attributes}s; must not be {@code null} 152 * 153 * @return an unmodifiable {@link List} consisting only of those {@link Attributes}s in the supplied {@link 154 * Collection} that {@linkplain #qualifier(Attributes) are qualifiers}; never {@code null} 155 * 156 * @exception NullPointerException if {@code c} is {@code null} 157 */ 158 public List<Attributes> qualifiers(final Collection<? extends Attributes> c) { 159 return switch (c) { 160 case Collection<?> c0 when c0.isEmpty() -> List.of(); 161 default -> { 162 final ArrayList<Attributes> list = new ArrayList<>(c.size()); 163 for (final Attributes a : c) { 164 if (this.qualifier(a)) { 165 list.add(this.normalize(a)); 166 } 167 } 168 list.trimToSize(); 169 yield Collections.unmodifiableList(list); 170 } 171 }; 172 } 173 174}