001/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
002 *
003 * Copyright © 2023 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.bean;
015
016import java.util.ArrayList;
017import java.util.Collection;
018import java.util.Collections;
019import java.util.List;
020import java.util.Map;
021
022import org.microbean.qualifier.NamedAttributeMap;
023
024public final class Qualifiers {
025
026  private static final NamedAttributeMap<String> QUALIFIER = new NamedAttributeMap<>("Qualifier");
027
028  private static final List<NamedAttributeMap<String>> QUALIFIER_LIST = List.of(QUALIFIER);
029
030  private static final NamedAttributeMap<?> ANY_QUALIFIER = new NamedAttributeMap<>("Any", Map.of(), Map.of(), QUALIFIER_LIST);
031
032  private static final List<NamedAttributeMap<?>> ANY_QUALIFIERS = List.of(ANY_QUALIFIER);
033
034  private static final NamedAttributeMap<?> DEFAULT_QUALIFIER = new NamedAttributeMap<>("Default", Map.of(), Map.of(), QUALIFIER_LIST);
035
036  private static final List<NamedAttributeMap<?>> DEFAULT_QUALIFIERS = List.of(DEFAULT_QUALIFIER);
037
038  private static final List<NamedAttributeMap<?>> ANY_AND_DEFAULT_QUALIFIERS = List.of(ANY_QUALIFIER, DEFAULT_QUALIFIER);
039
040  private Qualifiers() {
041    super();
042  }
043
044  public static final NamedAttributeMap<?> anyQualifier() {
045    return ANY_QUALIFIER;
046  }
047
048  public static final boolean anyQualifier(final NamedAttributeMap<?> nam) {
049    return ANY_QUALIFIER.equals(nam) && qualifier(nam);
050  }
051
052  public static final List<NamedAttributeMap<?>> anyQualifiers() {
053    return ANY_QUALIFIERS;
054  }
055
056  public static final List<NamedAttributeMap<?>> anyAndDefaultQualifiers() {
057    return ANY_AND_DEFAULT_QUALIFIERS;
058  }
059
060  public static final NamedAttributeMap<?> defaultQualifier() {
061    return DEFAULT_QUALIFIER;
062  }
063
064  public static final boolean defaultQualifier(final NamedAttributeMap<?> nam) {
065    return DEFAULT_QUALIFIER.equals(nam) && qualifier(nam);
066  }
067
068  public static final List<NamedAttributeMap<?>> defaultQualifiers() {
069    return DEFAULT_QUALIFIERS;
070  }
071
072  public static final NamedAttributeMap<?> qualifier() {
073    return QUALIFIER;
074  }
075
076  public static final boolean qualifier(final NamedAttributeMap<?> q) {
077    return q != null && qualifier(q.metadata());
078  }
079
080  private static final boolean qualifier(final Iterable<? extends NamedAttributeMap<?>> mds) {
081    for (final NamedAttributeMap<?> md : mds) {
082      if (QUALIFIER.equals(md) && md.metadata().isEmpty() || qualifier(md)) {
083        return true;
084      }
085    }
086    return false;
087  }
088
089  public static final List<NamedAttributeMap<?>> qualifiers(final Collection<? extends NamedAttributeMap<?>> c) {
090    if (c == null || c.isEmpty()) {
091      return List.of();
092    }
093    final ArrayList<NamedAttributeMap<?>> list = new ArrayList<>(c.size());
094    for (final NamedAttributeMap<?> a : c) {
095      if (qualifier(a)) {
096        list.add(a);
097      }
098    }
099    list.trimToSize();
100    return Collections.unmodifiableList(list);
101  }
102
103  public static final NamedAttributeMap<?> of(final NamedAttributeMap<?> nam) {
104    return switch (nam) {
105    case null -> throw new NullPointerException("nam");
106    case NamedAttributeMap<?> q when anyQualifier(q) -> anyQualifier();
107    case NamedAttributeMap<?> q when defaultQualifier(q) -> defaultQualifier();
108    case NamedAttributeMap<?> q when QUALIFIER.equals(q) && q.metadata().isEmpty() -> qualifier();
109    default -> nam;
110    };
111  }
112
113  public static final List<NamedAttributeMap<?>> of(final List<NamedAttributeMap<?>> list) {
114    return switch (list) {
115    case null -> throw new NullPointerException("list");
116    case List<NamedAttributeMap<?>> l when l.size() == 1 && anyQualifier(l.get(0)) -> anyQualifiers();
117    case List<NamedAttributeMap<?>> l when l.size() == 1 && defaultQualifier(l.get(0)) -> defaultQualifiers();
118    case List<NamedAttributeMap<?>> l when l.size() == 2 && anyQualifier(l.get(0)) && defaultQualifier(l.get(1)) -> anyAndDefaultQualifiers();
119    default -> list;
120    };
121  }
122
123}