/* * Copyright (c) 2008-2017, Hazelcast, Inc. All Rights Reserved. * * 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 com.hazelcast.query.impl.getters; import java.util.ArrayList; import java.util.List; /** * Represents multiple results from a single attribute extraction. * <p/> * MultiResult is an aggregate of results that is returned if the ValueExtractor returns multiple results due to a * reduce operation executed on a hierarchy of values. * <p/> * It sounds counter-intuitive, but a single extraction may return multiple values when arrays or collections are * involved. * <p/> * Let's have a look at the following data structure: * <code> * class Swap { * Leg legs[2]; * } * <p/> * class Leg { * String currency; * } * </code> * <p/> * The following extraction of the currency attribute <code>legs[any].currency</code> results in two currencies for each * Leg. In order to return both values in one result of the extract operation both currencies are returned in a * single MultiResult object where each result contains a name of the currency. * It allows the user to operate on multiple "reduced" values as if they were single-values. * <p/> * Let's have a look at the following queries: * <ul> * <li>leg[1].currency = 'EUR'</li> * <li>leg[any].currency = 'EUR'</li> * <p/> * </ul> * In the first query, the extraction will return just one currency, whereas the extraction in the second query will * return a MultiResult containing two currencies. * During the evaluation of the "=" equals predicate the MultiResult will be "unfolded" and the condition will * evaluated against all currencies from the MultiResult. If there is "any" currency that matches the condition the * whole predicate will be evaluated to "true" and the matching Swap will be returned. * As a result all Swaps will be returned where there's at lease one Leg with EUR currency. * <p/> * Other examples: * legs -> returns one 'single-value' result -> a collection of values * legs[0] -> returns one 'single result' - a Leg object * legs[0].currency -> returns one 'multi value' result - an array of Legs * legs[any] -> returns a MultiResult - that contains a collection of Leg objects * legs[any].currency -> returns a MultiResult - that contains a collection of String objects * * @param <T> type of the underlying result store in the MultiResult */ public class MultiResult<T> { private List<T> results; public MultiResult() { this.results = new ArrayList<T>(); } public MultiResult(List<T> results) { this.results = results; } /** * @param result result to be added to this MultiResult */ public void add(T result) { results.add(result); } /** * @return a mutable underlying list of collected results */ public List<T> getResults() { return results; } /** * @return true if the MultiResult is empty; false otherwise */ public boolean isEmpty() { return results.isEmpty(); } }