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

io.jstach.kiwi.kvs.KeyValuesServiceProvider Maven / Gradle / Ivy

The newest version!
package io.jstach.kiwi.kvs;

import java.net.URI;
import java.util.Optional;
import java.util.function.BiConsumer;

import io.jstach.kiwi.kvs.KeyValuesServiceProvider.KeyValuesLoaderFinder.LoaderContext;
import io.jstach.kiwi.kvs.KeyValuesServiceProvider.KeyValuesMediaFinder;
import io.jstach.kiwi.kvs.Variables.Parameters;

/**
 * A service provider interface (SPI) for extending Kiwi's capabilities to support
 * additional media types and URI patterns. Implementations of this interface can be
 * loaded using {@link java.util.ServiceLoader}.
 *
 * 

* This SPI allows customization and extension of Kiwi's loading mechanisms and media type * parsing. * *

* Note: This interface is sealed, and any sub-interface implementations must be * registered using {@code provides KeyValuesServiceProvider with ...} in the * {@code module-info.java} or as entries in the * {@code META-INF/services/io.jstach.kiwi.kvs.KeyValuesServiceProvider} file. * Sub-interfaces such as {@link KeyValuesLoaderFinder} and {@link KeyValuesMediaFinder} * should not be directly referenced in the service registration. * *

* Example use cases include adding support for custom media types or integrating * specialized URI loading logic. */ public sealed interface KeyValuesServiceProvider { /** * A service provider interface for finding {@link KeyValuesLoader} implementations * that can handle specific {@link KeyValuesResource} instances. */ public non-sealed interface KeyValuesLoaderFinder extends KeyValuesServiceProvider { /** * A context provided to {@link KeyValuesLoaderFinder} implementations to supply * necessary dependencies and services for creating a {@link KeyValuesLoader}. */ public sealed interface LoaderContext { /** * Retrieves the {@link KeyValuesEnvironment} for accessing system-level * resources and properties. * @return the environment instance */ KeyValuesEnvironment environment(); /** * Retrieves the {@link KeyValuesMediaFinder} for finding media types. * @return the media finder instance */ KeyValuesMediaFinder mediaFinder(); /** * Retrieves the {@link Variables} used for interpolation. * @return the variables instance */ Variables variables(); /** * Finds and returns a required parser for the specified * {@link KeyValuesResource}. Throws an exception if no parser is found. * @param resource the resource for which to find a parser * @return the parser for the resource * @throws KeyValuesMediaException if no parser is found for the resource's * media type */ default KeyValuesMedia.Parser requireParser(KeyValuesResource resource) { return mediaFinder() // .findByResource(resource) // .orElseThrow(() -> new KeyValuesMediaException("Media Type not found. resource: " + resource)) .parser(); } /** * Formats a {@link KeyValuesResource} into its key-value representation and * applies it to a given consumer. This method allows serializing the resource * into key-value pairs. * @param resource the resource to format * @param consumer the consumer to apply the formatted key-value pairs */ void formatResource(KeyValuesResource resource, BiConsumer consumer); /** * Formats a resource parameter key how it is represented as key in the parsed * resource. * @param resource resource to base the full parameter name on. * @param parameterName the short parameter from * {@link KeyValuesResource#parameters()}. * @return FQ parameter name. */ String formatParameterKey(KeyValuesResource resource, String parameterName); } /** * Finds a {@link KeyValuesLoader} capable of loading the specified * {@link KeyValuesResource} using the provided {@link LoaderContext}. * @param context the context containing dependencies and services * @param resource the resource for which a loader is sought * @return an {@link Optional} containing the loader if found, or empty if not */ public Optional findLoader(LoaderContext context, KeyValuesResource resource); } /** * A service provider interface (SPI) for filtering key values after a resource is * loaded. * *

* Filters are applied to modify, rename, or remove key-value pairs without altering * the original resource. This can be useful for transforming keys to a desired format * or eliminating unnecessary entries before the key values are processed further. * *

Usage

*

* A {@code KeyValuesFilter} is invoked after a {@link KeyValuesResource} is loaded * but before the resulting {@link KeyValues} are passed to the next stage of * processing. The filter uses a filter name and optional parameters to determine how * the key values should be modified. *

* * Filters are enabled by using the {@link KeyValuesResource#KEY_FILTER} key where the * default syntax is _filter_[resourceName]_[filterId]=expression. * *

Builtin Filters

* *

grep

* * Grep will filter keys by a regular expression. If the expression matches any part * of the key the key value is included. * * {@snippet lang = properties : * * _load_resource=... * _filter_resource_grep=someregex * * } * *

sed

* * Sed can change the keys name with subsitution or drop keys altogether. It follows a * subset of the UNIX sed command where "s" and "d" are * supported commands. * * {@snippet lang = properties : * * _load_resource=... * _filter_resource_sed=/match/ s/replace/withme/g * * } * *

Extensibility

*

* Implementations of {@code KeyValuesFilter} can be registered using the * {@code provides} directive in {@code module-info.java} or the * {@code META-INF/services} mechanism with the fully qualified name of * {@link KeyValuesServiceProvider}. Ideally the filter only applies filtering * based on the passed in filter name. Otherwise it should just return the * passed in key values. *

* *

* For example, to provide a custom implementation: *

*
{@code
	 * module my.module {
	 *     provides io.jstach.kiwi.kvs.KeyValuesServiceProvider with my.module.MyKeyValuesFilter;
	 * }
	 * }
* *

Method Details

* *

* The {@link #filter(FilterContext, KeyValues, Filter)} method performs the filtering * operation. *

*/ public non-sealed interface KeyValuesFilter extends KeyValuesServiceProvider { /** * Provides contextual information to a filter, including the environment and any * parameters specified for the filtering operation. * * @param environment the environment used to access system-level properties and * resources * @param parameters the parameters associated with the filtering operation */ public record FilterContext(KeyValuesEnvironment environment, Parameters parameters) { } /** * A filter description with filter identifier and expression which is the DSL * code that the filter will parse use to do filtering. * * @param filter filter identifier. * @param expression string code used by the filter to determine filtering. * @param name used to differentiate multiple calls to the same filter type when * looking up parameters. Defaults to empty string. */ public record Filter(String filter, String expression, String name) { } /** * Applies a filter to the given key-value pairs. The filter should ideally only * be applied if the passed filter parameter matches (filter name) otherwise the * filter just return the passed in key values. * @param context the filter context providing the environment and parameters * @param keyValues the key-value pairs to be filtered * @param filter filter description * @return a new {@link KeyValues} instance with the filtered key-value pairs */ KeyValues filter(FilterContext context, KeyValues keyValues, Filter filter); } /** * A service provider interface for finding {@link KeyValuesMedia} implementations * based on various attributes such as file extensions, media types, and URIs. */ public non-sealed interface KeyValuesMediaFinder extends KeyValuesServiceProvider { /** * Finds a {@link KeyValuesMedia} based on the attributes of a given * {@link KeyValuesResource}. * @param resource the resource for which to find the media type * @return an {@link Optional} containing the media if found, or empty if not */ default Optional findByResource(KeyValuesResource resource) { String mediaType = resource.mediaType(); if (mediaType == null) { return findByUri(resource.uri()); } return findByMediaType(mediaType); } /** * Finds a {@link KeyValuesMedia} based on a file extension. * @param ext the file extension (e.g., "properties") * @return an {@link Optional} containing the media if found, or empty if not */ public Optional findByExt(String ext); /** * Finds a {@link KeyValuesMedia} based on a media type string. * @param mediaType the media type (e.g., "application/json") * @return an {@link Optional} containing the media if found, or empty if not */ public Optional findByMediaType(String mediaType); /** * Finds a {@link KeyValuesMedia} based on a {@link URI}. * @param uri the URI to analyze * @return an {@link Optional} containing the media if found, or empty if not */ public Optional findByUri(URI uri); } } record DefaultLoaderContext(KeyValuesEnvironment environment, KeyValuesMediaFinder mediaFinder, Variables variables, KeyValuesResourceParser resourceParser) implements LoaderContext { static LoaderContext of(KeyValuesSystem system, Variables variables, KeyValuesResourceParser resourceParser) { return new DefaultLoaderContext(system.environment(), system.mediaFinder(), variables, resourceParser); } @Override public void formatResource(KeyValuesResource resource, BiConsumer consumer) { resourceParser.formatResource(resource, consumer); } @Override public String formatParameterKey(KeyValuesResource resource, String parameterName) { return resourceParser.formatParameterKey(resource, parameterName); } }




© 2015 - 2025 Weber Informatics LLC | Privacy Policy