001/*
002 *  Copyright 2021 Anyware Services
003 *
004 *  Licensed under the Apache License, Version 2.0 (the "License");
005 *  you may not use this file except in compliance with the License.
006 *  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
011 *  distributed under the License is distributed on an "AS IS" BASIS,
012 *  WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 *  See the License for the specific language governing permissions and
014 *  limitations under the License.
015 */
016
017package org.ametys.runtime.plugin.component;
018
019import java.util.Comparator;
020import java.util.Set;
021import java.util.TreeSet;
022import java.util.function.Function;
023
024/**
025 * Avalon based implementation of an {@link Prioritizable} ExtensionPoint.<br>
026 * @param <T> the type of the managed extensions, must implement {@link Prioritizable}
027 */
028public abstract class AbstractThreadSafeComponentPrioritizableExtensionPoint<T extends Prioritizable> extends AbstractThreadSafeComponentExtensionPoint<T>
029{
030    private Set<String> _sortedIds;
031    
032    @Override
033    public void initializeExtensions() throws Exception
034    {
035        super.initializeExtensions();
036        _sortedIds = new TreeSet<>(getComparator());
037        _sortedIds.addAll(super.getExtensionsIds());
038    }
039    
040    @Override
041    public Set<String> getExtensionsIds()
042    {
043        return _sortedIds;
044    }
045    
046    /**
047     * Define the comparator used to order components.
048     * Default is based on priority (could be ascending or descending depending of {@link #sortPriorityAscending()} value, then on the extension ID.
049     * @return the comparator used to order components
050     */
051    protected Comparator<String> getComparator()
052    {
053        return Comparator
054            // Comparing on priority (ascending or descending)
055            .<String, Integer>comparing(
056                id -> getExtension(id).getPriority(),
057                sortPriorityAscending()
058                    ? Comparator.naturalOrder()
059                    : Comparator.reverseOrder()
060            )
061            // Then comparing on extension id
062            .thenComparing(Function.identity());
063    }
064    
065    /**
066     * Define if the priority is ascending sorted or reversed, default implementation is <code>true</code>.
067     * @return <code>true</code> if the priority should be ascending.
068     */
069    protected boolean sortPriorityAscending()
070    {
071        return true;
072    }
073}