001/* 002 * GeoAPI - Java interfaces for OGC/ISO standards 003 * Copyright © 2006-2023 Open Geospatial Consortium, Inc. 004 * http://www.geoapi.org 005 * 006 * Licensed under the Apache License, Version 2.0 (the "License"); 007 * you may not use this file except in compliance with the License. 008 * You may obtain a copy of the License at 009 * 010 * http://www.apache.org/licenses/LICENSE-2.0 011 * 012 * Unless required by applicable law or agreed to in writing, software 013 * distributed under the License is distributed on an "AS IS" BASIS, 014 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 015 * See the License for the specific language governing permissions and 016 * limitations under the License. 017 */ 018package org.opengis.filter; 019 020import java.util.List; 021import java.util.Comparator; 022import org.opengis.annotation.UML; 023 024import static org.opengis.annotation.Obligation.MANDATORY; 025import static org.opengis.annotation.Specification.ISO_19143; 026 027 028/** 029 * Properties whose values shall be used to order the set of resources that satisfy a filter expression. 030 * {@code SortBy} provides an entry point to invoke the sorting mechanism of the filter expression processor. 031 * The sorting mechanism is not specified. The only requirement is that the sort sequence shall be consistent, 032 * given the same data set and sort request, between consecutive invocations of the sort. 033 * 034 * @author Martin Desruisseaux (Geomatys) 035 * @version 3.1 036 * 037 * @param <R> the type of resources (e.g. {@link org.opengis.feature.Feature}) to sort. 038 * 039 * @since 3.1 040 */ 041@UML(identifier="SortBy", specification=ISO_19143) 042public interface SortBy<R> extends Comparator<R> { 043 /** 044 * The properties whose values are used for sorting. The list shall have a minimum of one element. 045 * In the event that multiple elements exist, the sequence of the {@code SortProperty} elements 046 * determines the order of ordering. 047 * 048 * @return properties whose values are used for sorting. 049 */ 050 @UML(identifier="sortProperty", obligation=MANDATORY, specification=ISO_19143) 051 List<SortProperty<R>> getSortProperties(); 052 053 /** 054 * Compares two resources for order. Returns a negative number if {@code r1} should be sorted before {@code r2}, 055 * a positive number if {@code r2} should be after {@code r1}, or 0 if both resources are equal. 056 * The ordering of null resources or null property values is unspecified. 057 * 058 * <p>The comparison shall be consistent (ignoring unspecified aspects such as null values) 059 * with a comparison done "manually" by the following code:</p> 060 * 061 * {@snippet lang="java" : 062 * for (SortProperty<R> p : getSortProperties()) { 063 * int c = p.compare(r1, r2); 064 * if (c != 0) return c; 065 * } 066 * return 0; 067 * } 068 * 069 * <p>In order words, it shall be possible for the users to build their own SQL (or other language) query 070 * using above information and get the same results without invoking this {@code compare(…)} method.</p> 071 * 072 * @param r1 the first resource to compare. 073 * @param r2 the second resource to compare. 074 * @return negative if the first resource is before the second, positive for the converse, or 0 if equal. 075 * @throws InvalidFilterValueException if an expression cannot be applied on the given resources. 076 * @throws ClassCastException if the types of {@linkplain ValueReference#apply(Object) property values} 077 * prevent them from being compared by this comparator. 078 * 079 * @see SortProperty#compare(Object, Object) 080 */ 081 @Override 082 default int compare(final R r1, final R r2) { 083 for (final SortProperty<R> p : getSortProperties()) { 084 final int c = p.compare(r1, r2); 085 if (c != 0) return c; 086 } 087 return 0; 088 } 089}