/* * Copyright 2015 Lukas Krejci * * 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.revapi; import java.util.Iterator; import java.util.List; import java.util.SortedSet; import javax.annotation.Nonnull; import javax.annotation.Nullable; import org.revapi.query.Filter; /** * An element in a forest representation of given "language" under API inspection. In case of programming languages this * will usually be a (trimmed down) abstract syntax tree, in case of XSD this can be an actual DOM tree. * * <p>An element is comparable with all other element types for given language, giving a total ordering across all and * any element types given language defines. * * @author Lukas Krejci * @since 0.1 */ public interface Element extends Comparable<Element> { /** * Casts this element to the provided type. * @param type the type to cast this instance to * @return this cast as the provided type * @throws ClassCastException if this instance cannot be cast to the provided type */ default <T extends Element> T as(Class<T> type) { return type.cast(this); } /** * @return the API version this element comes from */ @Nonnull API getApi(); /** * @return the archive the element comes from or null if that cannot be determined */ @Nullable Archive getArchive(); /** * @return the parent element or null if this is a root element */ @Nullable Element getParent(); /** * Sets a new parent. * @param parent the new parent of this element */ void setParent(@Nullable Element parent); @Nonnull SortedSet<? extends Element> getChildren(); /** * Provides the full "path" to the element in the forest in a human readable way. * This method is meant to be used by the reporters to identify the element in the reports. * * @return human readable representation of the element */ @Nonnull String getFullHumanReadableString(); /** * This method is functionally equivalent to {@link #searchChildren(java.util.List, java.lang.Class, boolean, * org.revapi.query.Filter)} but returns the result in a newly allocated list instance. This is basically * a convenience method to enable a more succinct expressions. * * @param <T> the type of the elements to look for * @param resultType the type of the elements to look for * @param recurse false to search only in direct children of the element, true to search recursively * @param filter optional filter to further trim the number of results @return the list of child elements of * given type potentially satisfying given filter * * @return the list of found elements */ @Nonnull <T extends Element> List<T> searchChildren(@Nonnull Class<T> resultType, boolean recurse, @Nullable Filter<? super T> filter); /** * Recursively searches the children of this element for elements of given type, potentially applicable to given * filter. * * <p>This is identical to {@link #searchChildren(Class, boolean, org.revapi.query.Filter)} in behavior but avoids * the instantiation of a new list. * * @param <T> the type of the elements to look for * @param results the list of the results to fill * @param resultType the type of the elements to look for * @param recurse false to search only in direct children of the element, true to search recursively * @param filter optional filter to further trim the number of results */ <T extends Element> void searchChildren(@Nonnull List<T> results, @Nonnull Class<T> resultType, boolean recurse, @Nullable Filter<? super T> filter); /** * Similar to search methods but avoids the traversal over the whole forest. Instead the traversal is incremental * and governed by the returned iterator. * * @param <T> the type of the elements to look for * @param resultType the type of elements to look for * @param recurse if true, the iterator traverses the element forest using depth first search * @param filter optional filter to further trim the number of results * * @return the iterator that will iterate over the results * * @see #searchChildren(Class, boolean, org.revapi.query.Filter) */ @Nonnull <T extends Element> Iterator<T> iterateOverChildren(@Nonnull Class<T> resultType, boolean recurse, @Nullable Filter<? super T> filter); }