All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.tangosol.util.Extractors Maven / Gradle / Ivy

There is a newer version: 24.09
Show newest version
/*
 * Copyright (c) 2000, 2021, Oracle and/or its affiliates.
 *
 * Licensed under the Universal Permissive License v 1.0 as shown at
 * http://oss.oracle.com/licenses/upl.
 */
package com.tangosol.util;

import com.tangosol.internal.util.invoke.Lambdas;
import com.tangosol.io.pof.generator.PortableTypeGenerator;

import com.tangosol.io.pof.reflect.PofNavigator;
import com.tangosol.io.pof.reflect.PofReflectionHelper;
import com.tangosol.io.pof.reflect.SimplePofPath;

import com.tangosol.io.pof.schema.annotation.PortableType;

import com.tangosol.util.extractor.ChainedExtractor;
import com.tangosol.util.extractor.ChainedFragmentExtractor;
import com.tangosol.util.extractor.FragmentExtractor;
import com.tangosol.util.extractor.IdentityExtractor;
import com.tangosol.util.extractor.MultiExtractor;
import com.tangosol.util.extractor.PofExtractor;
import com.tangosol.util.extractor.ScriptValueExtractor;
import com.tangosol.util.extractor.UniversalExtractor;

import java.util.Arrays;
import java.util.List;
import java.util.Objects;

/**
 * Simple Extractor DSL.
 * 

* The methods in this class are for the most part simple factory methods for * various {@link ValueExtractor} classes, but in some cases provide additional type * safety. They also tend to make the code more readable, especially if imported * statically, so their use is strongly encouraged in lieu of direct construction * of {@code Extractor} classes. * * @author lh, hr, as, mf 2018.06.14 */ public class Extractors { /** * Returns an extractor that always returns its input argument. * * @param the type of the input and output objects to the function * * @return an extractor that always returns its input argument */ public static ValueExtractor identity() { return IdentityExtractor.INSTANCE(); } /** * Returns an extractor that extracts the value of the specified field. * * @param from the name of the field or method to extract the value from * * @param the type of the object to extract from * @param the type of the extracted value * * @return an extractor that extracts the value of the specified field * * @see UniversalExtractor */ public static ValueExtractor extract(String from) { return new UniversalExtractor<>(from); } /** * Returns an extractor that extracts the value of the specified field. * * @param from the name of the method to extract the value from (which must be * the full method name) * @param aoParam the parameters to pass to the method * * @param the type of the object to extract from * @param the type of the extracted value * * @return an extractor that extracts the value of the specified field * * @see UniversalExtractor */ public static ValueExtractor extract(String from, Object... aoParam) { if (!from.endsWith("()")) { from = from + "()"; } return new UniversalExtractor<>(from, aoParam); } /** * Returns an extractor that extracts the specified fields * and returns the extracted values in a {@link List}. * * @param fields the field names to extract * * @param the type of the object to extract from * * @return an extractor that extracts the value(s) of the specified field(s) * * @throws IllegalArgumentException if the fields parameter is null or an * empty array * * @see UniversalExtractor */ @SuppressWarnings("unchecked") public static ValueExtractor> multi(String... fields) { if (fields == null || fields.length == 0) { throw new IllegalArgumentException("The fields parameter cannot be null or empty"); } ValueExtractor[] aExtractor = Arrays.stream(fields) .filter(Objects::nonNull) .map(Extractors::chained) .toArray(ValueExtractor[]::new); if (aExtractor.length == 0) { throw new IllegalArgumentException("The fields parameter must contain at least one non-null element"); } return multi(aExtractor); } /** * Returns an extractor that extracts values using the specified * {@link ValueExtractor}s and returns the extracted values in a {@link List}. * * @param extractors the {@link ValueExtractor}s to use to extract the list of values * * @param the type of the object to extract from * * @return an extractor that extracts the value(s) of the specified field(s) * * @throws IllegalArgumentException if the fields parameter is null or an * empty array * * @see UniversalExtractor */ @SuppressWarnings("unchecked") public static ValueExtractor> multi(ValueExtractor... extractors) { return new MultiExtractor(extractors); } /** * Returns an extractor that extracts the specified fields * where extraction occurs in a chain where the result of each * field extraction is the input to the next extractor. The result * returned is the result of the final extractor in the chain. * * @param fields the field names to extract (if any field name contains a dot '.' * that field name is split into multiple field names delimiting on * the dots. * * @param the type of the object to extract from * * @return an extractor that extracts the value(s) of the specified field(s) * * @throws IllegalArgumentException if the fields parameter is null or an * empty array * * @see UniversalExtractor */ @SuppressWarnings("unchecked") public static ValueExtractor chained(String... fields) { if (fields == null || fields.length == 0) { throw new IllegalArgumentException("The fields parameter cannot be null or empty"); } ValueExtractor[] aExtractor = Arrays.stream(fields) .filter(Objects::nonNull) .map(s -> s.split("\\.")) .flatMap(Arrays::stream) .map(Extractors::extract) .toArray(ValueExtractor[]::new); if (aExtractor.length == 0) { throw new IllegalArgumentException("The fields parameter must contain at least one non-null element"); } if (aExtractor.length == 1) { return aExtractor[0]; } return chained(aExtractor); } /** * Returns an extractor that extracts the specified fields * where extraction occurs in a chain where the result of each * field extraction is the input to the next extractor. The result * returned is the result of the final extractor in the chain. * * @param extractors the {@link ValueExtractor}s to use to extract the list of values * * @param the type of the object to extract from * * @return an extractor that extracts the value(s) of the specified field(s) * * @throws IllegalArgumentException if the extractors parameter is null or an * empty array * * @see UniversalExtractor */ @SuppressWarnings("unchecked") public static ValueExtractor chained(ValueExtractor... extractors) { if (extractors == null || extractors.length == 0) { throw new IllegalArgumentException("The extractors parameter cannot be null or empty"); } if (extractors.length == 1) { return (ValueExtractor) extractors[0]; } return new ChainedExtractor<>(extractors); } /** * Returns an extractor that casts its input argument. * * @param the type of the input objects to the function * @param the type of the output objects to the function * * @return an extractor that always returns its input argument */ @SuppressWarnings("unchecked") public static ValueExtractor identityCast() { return IdentityExtractor.INSTANCE; } /** * Returns an extractor that extracts the value of the specified index(es) * from a POF encoded binary value. * * @param indexes the POF index(es) to extract * * @param the type of the object to extract from * * @return an extractor that extracts the value of the specified field */ public static ValueExtractor fromPof(int... indexes) { return fromPof(null, indexes); } /** * Returns an extractor that extracts the value of the specified index(es) * from a POF encoded binary value. * * @param indexes the POF index(es) to extract * * @param the type of the POF serialized object to extract from * @param the type of the extracted value * * @return an extractor that extracts the value of the specified field * * @throws NullPointerException if the indexes parameter is null */ public static ValueExtractor fromPof(Class cls, int... indexes) { return fromPof(cls, new SimplePofPath(Objects.requireNonNull(indexes))); } /** * Returns an extractor that extracts the value of the specified index(es) * from a POF encoded {@link PortableType @PortableType}. *

* The specified class *must* be marked with {@link PortableType @PortableType} * annotation and instrumented using {@link PortableTypeGenerator} in order * for this method to work. Otherwise, an {@link IllegalArgumentException} * will be thrown. * * @param sPath the path of the property to extract * * @param the type of the POF serialized object to extract from * @param the type of the extracted value * * @return an extractor that extracts the value of the specified field * * @throws NullPointerException if the indexes parameter is null * @throws IllegalArgumentException if the specified class isn't a portable * type, or the specified property path doesn't exist */ public static ValueExtractor fromPof(Class cls, String sPath) { return fromPof(cls, PofReflectionHelper.getPofNavigator(cls, sPath)); } /** * Returns an extractor that extracts the value of the specified index(es) * from a POF encoded binary value. * * @param navigator the {@link PofNavigator} to use to determine the POF path to extract * * @param the type of the POF serialized object to extract from * @param the type of the extracted value * * @return an extractor that extracts the value of the specified field * * @throws NullPointerException if the indexes parameter is null */ public static ValueExtractor fromPof(Class cls, PofNavigator navigator) { return new PofExtractor<>(cls, navigator); } /** * Instantiate a {@code ValueExtractor} that is implemented using the specified * language. * * @param sLanguage the string specifying one of the supported languages * @param sScriptPath the path where the script reside, relative to root * @param aoArgs the arguments to be passed to the script * @param the type of object to extract from * @param the type of the extracted value * * @return An instance of {@link ValueExtractor} * * @throws ScriptException if the {@code script} cannot be loaded or * any errors occur during its execution * @throws IllegalArgumentException if the specified language is not supported * * @since 14.1.1.0 */ public static ValueExtractor script(String sLanguage, String sScriptPath, Object... aoArgs) { return new ScriptValueExtractor<>(sLanguage, sScriptPath, aoArgs); } /** * Return a {@code ValueExtractor} that extracts a {@link Fragment} from a * target object. * * @param aExtractors an array of extractors to pass to {@link FragmentExtractor} * @param the type of object to extract from * * @return a {@code ValueExtractor} that extracts a {@link Fragment} from a * target object */ @SafeVarargs public static ValueExtractor> fragment(ValueExtractor... aExtractors) { return new FragmentExtractor<>(aExtractors); } /** * Return a {@code ValueExtractor} that extracts a nested {@link Fragment} from a * property of the target object. * * @param from an extractor for the nested property to extract the fragment from * @param aExtractors an array of extractors to pass to {@link FragmentExtractor} * @param the type of the root object to extract from * * @return a {@code ValueExtractor} that extracts a {@link Fragment} from a * target object's property */ @SafeVarargs public static ValueExtractor> fragment(ValueExtractor from, ValueExtractor... aExtractors) { return new ChainedFragmentExtractor<>(from, aExtractors); } }





© 2015 - 2024 Weber Informatics LLC | Privacy Policy