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; 021import java.util.Objects; 022 023import org.microbean.qualifier.NamedAttributeMap; 024 025/** 026 * A utility class providing methods that work with interceptor bindings. 027 * 028 * @author <a href="https://about.me/lairdnelson" target="_top">Laird Nelson</a> 029 */ 030public final class InterceptorBindings { 031 032 private static final NamedAttributeMap<String> INTERCEPTOR_BINDING = new NamedAttributeMap<>("InterceptorBinding"); 033 034 private static final List<NamedAttributeMap<String>> INTERCEPTOR_BINDING_LIST = List.of(INTERCEPTOR_BINDING); 035 036 private static final NamedAttributeMap<String> ANY_INTERCEPTOR_BINDING = 037 new NamedAttributeMap<>("Any", Map.of(), Map.of(), INTERCEPTOR_BINDING_LIST); 038 039 private InterceptorBindings() { 040 super(); 041 } 042 043 public static final NamedAttributeMap<String> anyInterceptorBinding() { 044 return ANY_INTERCEPTOR_BINDING; 045 } 046 047 public static final boolean anyInterceptorBinding(final NamedAttributeMap<?> nam) { 048 return ANY_INTERCEPTOR_BINDING.equals(nam) && interceptorBinding(nam); 049 } 050 051 public static final NamedAttributeMap<String> interceptorBinding() { 052 return INTERCEPTOR_BINDING; 053 } 054 055 public static final boolean interceptorBinding(final NamedAttributeMap<?> a) { 056 return a != null && interceptorBinding(a.metadata()); 057 } 058 059 private static final boolean interceptorBinding(final Iterable<? extends NamedAttributeMap<?>> mds) { 060 for (final NamedAttributeMap<?> md : mds) { 061 if (md.equals(INTERCEPTOR_BINDING) && md.metadata().isEmpty() || interceptorBinding(md)) { 062 return true; 063 } 064 } 065 return false; 066 } 067 068 /** 069 * Given a {@link Collection} of {@link NamedAttributeMap}s, returns a {@link List} consisting of those {@link 070 * NamedAttributeMap} instances that are {@linkplain #interceptorBinding() deemed to be interceptor bindings}. 071 * 072 * @param c a {@link Collection}; must not be {@code null} 073 * 074 * @return a {@link List} of interceptor bindings 075 */ 076 public static final List<NamedAttributeMap<?>> interceptorBindings(final Collection<? extends NamedAttributeMap<?>> c) { 077 if (c.isEmpty()) { 078 return List.of(); 079 } 080 final ArrayList<NamedAttributeMap<?>> list = new ArrayList<>(c.size()); 081 for (final NamedAttributeMap<?> nam : c) { 082 if (interceptorBinding(nam)) { 083 list.add(nam); 084 } 085 } 086 list.trimToSize(); 087 return Collections.unmodifiableList(list); 088 } 089 090 public static final NamedAttributeMap<?> targetClassInterceptorBinding(final String type) { 091 return new NamedAttributeMap<String>("TargetClass", Map.of("class", Objects.requireNonNull(type, "type")), Map.of(), INTERCEPTOR_BINDING_LIST); 092 } 093 094 // Is nam a TargetClass interceptor binding? 095 public static final boolean targetClassInterceptorBinding(final NamedAttributeMap<?> nam) { 096 return nam.name().equals("TargetClass") && interceptorBinding(nam); 097 } 098 099}