
org.microbean.bean.Beans Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of microbean-bean Show documentation
Show all versions of microbean-bean Show documentation
microBean™ Bean: Utility classes for implementing beans.
/* -*- mode: Java; c-basic-offset: 2; indent-tabs-mode: nil; coding: utf-8-unix -*-
*
* Copyright © 2024 microBean™.
*
* Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with
* the License. You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on
* an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the
* specific language governing permissions and limitations under the License.
*/
package org.microbean.bean;
import java.lang.System.Logger;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Objects;
import java.util.Set;
import java.util.concurrent.ConcurrentHashMap;
import static java.util.HashSet.newHashSet;
/**
* A {@link Selectable} and {@link Reducible} implementation that works with {@link Bean} and {@link
* AttributedType} instances.
*
* @author Laird Nelson
*
* @see #Beans(Selectable, Reducible)
*
* @see Selectable
*
* @see Reducible
*
* @see Reducer
*
* @see RankedReducer
*
* @see Bean
*
* @see AttributedType
*/
public final class Beans implements Selectable>, Reducible> {
/*
* Static fields.
*/
private static final Logger LOGGER = System.getLogger(Beans.class.getName());
private static final Comparator> byRankComparator = Comparator
.>comparingInt(Ranked::rank)
.reversed();
private static final Comparator> byAlternateThenByRankComparator = Comparator
., Boolean>comparing(Ranked::alternate)
.reversed()
.thenComparing(byRankComparator);
/*
* Instance fields.
*/
private final Selectable> s;
private final Reducible> r;
/*
* Constructors.
*/
public Beans(final Selectable> s,
final Reducible> r) {
this.s = Objects.requireNonNull(s, "s");
this.r = Objects.requireNonNull(r, "r");
}
/*
* Instance methods.
*/
@Override // Selectable>
public final List> select(final AttributedType c) {
return this.s.select(c);
}
@Override // Reducible>
public final Bean> reduce(final AttributedType c) {
return this.r.reduce(c);
}
/*
* Static methods.
*/
public static final Selectable> cachingSelectableOf(final Matcher super AttributedType, ? super Id> idMatcher,
final Map extends AttributedType, ? extends List>> selections,
final Collection extends Bean>> beans) {
Objects.requireNonNull(idMatcher, "idMatcher");
final Map>> selectionCache = new ConcurrentHashMap<>();
final ArrayList> newBeans = new ArrayList<>(31); // 31 == arbitrary
final Set> newBeansSet = newHashSet(31); // 31 == arbitrary
for (final Entry extends AttributedType, ? extends List>> e : selections.entrySet()) {
final List> selection = e.getValue();
if (!selection.isEmpty()) {
final Set> newSelectionSet = newHashSet(7); // 7 == arbitrary
final ArrayList> newSelection = new ArrayList<>(selection.size());
for (final Bean> b : selection) {
if (newSelectionSet.add(b)) {
newSelection.add(b);
}
if (newBeansSet.add(b)) {
newBeans.add(b);
}
}
newSelectionSet.clear();
newSelection.trimToSize();
Collections.sort(newSelection, byAlternateThenByRankComparator);
selectionCache.put(e.getKey(), Collections.unmodifiableList(newSelection));
}
}
for (final Bean> bean : beans) {
if (newBeansSet.add(bean)) {
newBeans.add(bean);
}
}
newBeansSet.clear();
if (newBeans.isEmpty()) {
return Beans::empty;
}
Collections.sort(newBeans, byAlternateThenByRankComparator);
newBeans.trimToSize();
return attributedType -> selectionCache.computeIfAbsent(attributedType, at -> newBeans.stream().filter(b -> idMatcher.test(at, b.id())).toList());
}
private static final List empty(final C ignored) {
return List.of();
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy