001/*
002 * Licensed to the Apache Software Foundation (ASF) under one or more
003 * contributor license agreements.  See the NOTICE file distributed with
004 * this work for additional information regarding copyright ownership.
005 * The ASF licenses this file to You under the Apache License, Version 2.0
006 * (the "License"); you may not use this file except in compliance with
007 * the License.  You may obtain a copy of the License at
008 *
009 *      http://www.apache.org/licenses/LICENSE-2.0
010 *
011 * Unless required by applicable law or agreed to in writing, software
012 * distributed under the License is distributed on an "AS IS" BASIS,
013 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
014 * See the License for the specific language governing permissions and
015 * limitations under the License.
016 */
017package org.apache.juneau.reflect;
018
019import static org.apache.juneau.internal.ConsumerUtils.*;
020
021import java.lang.annotation.*;
022import java.util.*;
023import java.util.function.*;
024
025/**
026 * An ordered list of annotations and the classes/methods/packages they were found on.
027 *
028 * <h5 class='section'>See Also:</h5><ul>
029 * </ul>
030 *
031 * @serial exclude
032 */
033public class AnnotationList extends ArrayList<AnnotationInfo<?>> {
034   private static final long serialVersionUID = 1L;
035
036   private static final Comparator<AnnotationInfo<?>> RANK_COMPARATOR = (o1, o2) -> o1.rank - o2.rank;
037
038   /**
039    * Sort the annotations in this list based on rank.
040    *
041    * @return This object.
042    */
043   public AnnotationList sort() {
044      Collections.sort(this, RANK_COMPARATOR);
045      return this;
046   }
047
048   /**
049    * Performs an action on the specified matching values from all annotations in this list.
050    *
051    * @param <T> The annotation value type.
052    * @param type The annotation value type.
053    * @param name The annotation value name.
054    * @param filter A predicate to apply to the value to determine if action should be performed.  Can be <jk>null</jk>.
055    * @param action An action to perform on the value.
056    * @return This object.
057    */
058   public <T> AnnotationList forEachValue(Class<T> type, String name, Predicate<T> filter, Consumer<T> action) {
059      forEach(x -> x.forEachValue(type, name, filter, action));
060      return this;
061   }
062
063   /**
064    * Performs an action on all matching annotations in this list.
065    *
066    * @param <A> The annotation type.
067    * @param type The annotation type.
068    * @param filter A predicate to apply to the entries to determine if action should be performed.  Can be <jk>null</jk>.
069    * @param action An action to perform on the entry.
070    * @return This object.
071    */
072   @SuppressWarnings("unchecked")
073   public <A extends Annotation> AnnotationList forEach(Class<A> type, Predicate<AnnotationInfo<A>> filter, Consumer<AnnotationInfo<A>> action) {
074      forEach(x -> {
075         if (x.isType(type))
076            consume(filter, action, (AnnotationInfo<A>)x);
077      });
078      return this;
079   }
080
081   /**
082    * Performs an action on all matching annotations in this list.
083    *
084    * @param <A> The annotation type.
085    * @param filter A predicate to apply to the entries to determine if action should be performed.  Can be <jk>null</jk>.
086    * @param action An action to perform on the entry.
087    * @return This object.
088    */
089   public <A extends Annotation> AnnotationList forEach(Predicate<AnnotationInfo<?>> filter, Consumer<AnnotationInfo<?>> action) {
090      forEach(x -> consume(filter, action, x));
091      return this;
092   }
093}