/*
 * Licensed to the Apache Software Foundation (ASF) under one or more
 * contributor license agreements.  See the NOTICE file distributed with
 * this work for additional information regarding copyright ownership.
 * The ASF licenses this file to You 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.apache.camel.builder.endpoint.dsl;

import java.util.List;
import java.util.Properties;
import javax.annotation.Generated;
import org.apache.camel.ExchangePattern;
import org.apache.camel.builder.EndpointConsumerBuilder;
import org.apache.camel.builder.EndpointProducerBuilder;
import org.apache.camel.builder.endpoint.AbstractEndpointBuilder;
import org.apache.camel.spi.ExceptionHandler;

/**
 * The jcache component enables you to perform caching operations using
 * JSR107/JCache as cache implementation.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface JCacheEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the JCache component.
     */
    public interface JCacheEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedJCacheEndpointConsumerBuilder advanced() {
            return (AdvancedJCacheEndpointConsumerBuilder) this;
        }
        /**
         * A Configuration for the Cache.
         * 
         * The option is a: <code>javax.cache.configuration.Configuration</code>
         * type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder cacheConfiguration(
                Object cacheConfiguration) {
            doSetProperty("cacheConfiguration", cacheConfiguration);
            return this;
        }
        /**
         * A Configuration for the Cache.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Configuration</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder cacheConfiguration(
                String cacheConfiguration) {
            doSetProperty("cacheConfiguration", cacheConfiguration);
            return this;
        }
        /**
         * The Properties for the javax.cache.spi.CachingProvider to create the
         * CacheManager.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder cacheConfigurationProperties(
                Properties cacheConfigurationProperties) {
            doSetProperty("cacheConfigurationProperties", cacheConfigurationProperties);
            return this;
        }
        /**
         * The Properties for the javax.cache.spi.CachingProvider to create the
         * CacheManager.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder cacheConfigurationProperties(
                String cacheConfigurationProperties) {
            doSetProperty("cacheConfigurationProperties", cacheConfigurationProperties);
            return this;
        }
        /**
         * The fully qualified class name of the
         * javax.cache.spi.CachingProvider.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder cachingProvider(
                String cachingProvider) {
            doSetProperty("cachingProvider", cachingProvider);
            return this;
        }
        /**
         * An implementation specific URI for the CacheManager.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * Whether management gathering is enabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder managementEnabled(
                boolean managementEnabled) {
            doSetProperty("managementEnabled", managementEnabled);
            return this;
        }
        /**
         * Whether management gathering is enabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder managementEnabled(
                String managementEnabled) {
            doSetProperty("managementEnabled", managementEnabled);
            return this;
        }
        /**
         * If read-through caching should be used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder readThrough(boolean readThrough) {
            doSetProperty("readThrough", readThrough);
            return this;
        }
        /**
         * If read-through caching should be used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder readThrough(String readThrough) {
            doSetProperty("readThrough", readThrough);
            return this;
        }
        /**
         * Whether statistics gathering is enabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder statisticsEnabled(
                boolean statisticsEnabled) {
            doSetProperty("statisticsEnabled", statisticsEnabled);
            return this;
        }
        /**
         * Whether statistics gathering is enabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder statisticsEnabled(
                String statisticsEnabled) {
            doSetProperty("statisticsEnabled", statisticsEnabled);
            return this;
        }
        /**
         * If cache should use store-by-value or store-by-reference semantics.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder storeByValue(boolean storeByValue) {
            doSetProperty("storeByValue", storeByValue);
            return this;
        }
        /**
         * If cache should use store-by-value or store-by-reference semantics.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder storeByValue(String storeByValue) {
            doSetProperty("storeByValue", storeByValue);
            return this;
        }
        /**
         * If write-through caching should be used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder writeThrough(boolean writeThrough) {
            doSetProperty("writeThrough", writeThrough);
            return this;
        }
        /**
         * If write-through caching should be used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointConsumerBuilder writeThrough(String writeThrough) {
            doSetProperty("writeThrough", writeThrough);
            return this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder bridgeErrorHandler(
                boolean bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Allows for bridging the consumer to the Camel routing Error Handler,
         * which mean any exceptions occurred while the consumer is trying to
         * pickup incoming messages, or the likes, will now be processed as a
         * message and handled by the routing Error Handler. By default the
         * consumer will use the org.apache.camel.spi.ExceptionHandler to deal
         * with exceptions, that will be logged at WARN or ERROR level and
         * ignored.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * Events a consumer should filter. If using filteredEvents option, then
         * eventFilters one will be ignored.
         * 
         * The option is a:
         * <code>java.util.List&lt;javax.cache.event.EventType&gt;</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder filteredEvents(
                List<EventType> filteredEvents) {
            doSetProperty("filteredEvents", filteredEvents);
            return this;
        }
        /**
         * Events a consumer should filter. If using filteredEvents option, then
         * eventFilters one will be ignored.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;javax.cache.event.EventType&gt;</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder filteredEvents(
                String filteredEvents) {
            doSetProperty("filteredEvents", filteredEvents);
            return this;
        }
        /**
         * if the old value is required for events.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder oldValueRequired(
                boolean oldValueRequired) {
            doSetProperty("oldValueRequired", oldValueRequired);
            return this;
        }
        /**
         * if the old value is required for events.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder oldValueRequired(
                String oldValueRequired) {
            doSetProperty("oldValueRequired", oldValueRequired);
            return this;
        }
        /**
         * if the event listener should block the thread causing the event.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder synchronous(boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * if the event listener should block the thread causing the event.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: consumer
         */
        default JCacheEndpointConsumerBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the JCache component.
     */
    public interface AdvancedJCacheEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default JCacheEndpointConsumerBuilder basic() {
            return (JCacheEndpointConsumerBuilder) this;
        }
        /**
         * The CacheEntryEventFilter. If using eventFilters option, then
         * filteredEvents one will be ignored.
         * 
         * The option is a:
         * <code>java.util.List&lt;javax.cache.event.CacheEntryEventFilter&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJCacheEndpointConsumerBuilder eventFilters(
                List<Object> eventFilters) {
            doSetProperty("eventFilters", eventFilters);
            return this;
        }
        /**
         * The CacheEntryEventFilter. If using eventFilters option, then
         * filteredEvents one will be ignored.
         * 
         * The option will be converted to a
         * <code>java.util.List&lt;javax.cache.event.CacheEntryEventFilter&gt;</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJCacheEndpointConsumerBuilder eventFilters(
                String eventFilters) {
            doSetProperty("eventFilters", eventFilters);
            return this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option is a: <code>org.apache.camel.spi.ExceptionHandler</code>
         * type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJCacheEndpointConsumerBuilder exceptionHandler(
                ExceptionHandler exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * To let the consumer use a custom ExceptionHandler. Notice if the
         * option bridgeErrorHandler is enabled then this option is not in use.
         * By default the consumer will deal with exceptions, that will be
         * logged at WARN or ERROR level and ignored.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.ExceptionHandler</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJCacheEndpointConsumerBuilder exceptionHandler(
                String exceptionHandler) {
            doSetProperty("exceptionHandler", exceptionHandler);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option is a: <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJCacheEndpointConsumerBuilder exchangePattern(
                ExchangePattern exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Sets the exchange pattern when the consumer creates an exchange.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.ExchangePattern</code> type.
         * 
         * Group: consumer (advanced)
         */
        default AdvancedJCacheEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * The CacheLoader factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheLoader&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder cacheLoaderFactory(
                Object cacheLoaderFactory) {
            doSetProperty("cacheLoaderFactory", cacheLoaderFactory);
            return this;
        }
        /**
         * The CacheLoader factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheLoader&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder cacheLoaderFactory(
                String cacheLoaderFactory) {
            doSetProperty("cacheLoaderFactory", cacheLoaderFactory);
            return this;
        }
        /**
         * The CacheWriter factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheWriter&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder cacheWriterFactory(
                Object cacheWriterFactory) {
            doSetProperty("cacheWriterFactory", cacheWriterFactory);
            return this;
        }
        /**
         * The CacheWriter factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheWriter&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder cacheWriterFactory(
                String cacheWriterFactory) {
            doSetProperty("cacheWriterFactory", cacheWriterFactory);
            return this;
        }
        /**
         * Configure if a cache need to be created if it does exist or can't be
         * pre-configured.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder createCacheIfNotExists(
                boolean createCacheIfNotExists) {
            doSetProperty("createCacheIfNotExists", createCacheIfNotExists);
            return this;
        }
        /**
         * Configure if a cache need to be created if it does exist or can't be
         * pre-configured.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder createCacheIfNotExists(
                String createCacheIfNotExists) {
            doSetProperty("createCacheIfNotExists", createCacheIfNotExists);
            return this;
        }
        /**
         * The ExpiryPolicy factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.expiry.ExpiryPolicy&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder expiryPolicyFactory(
                Object expiryPolicyFactory) {
            doSetProperty("expiryPolicyFactory", expiryPolicyFactory);
            return this;
        }
        /**
         * The ExpiryPolicy factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.expiry.ExpiryPolicy&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder expiryPolicyFactory(
                String expiryPolicyFactory) {
            doSetProperty("expiryPolicyFactory", expiryPolicyFactory);
            return this;
        }
        /**
         * Configure if a camel-cache should try to find implementations of
         * jcache api in runtimes like OSGi.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder lookupProviders(
                boolean lookupProviders) {
            doSetProperty("lookupProviders", lookupProviders);
            return this;
        }
        /**
         * Configure if a camel-cache should try to find implementations of
         * jcache api in runtimes like OSGi.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointConsumerBuilder lookupProviders(
                String lookupProviders) {
            doSetProperty("lookupProviders", lookupProviders);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the JCache component.
     */
    public interface JCacheEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedJCacheEndpointProducerBuilder advanced() {
            return (AdvancedJCacheEndpointProducerBuilder) this;
        }
        /**
         * A Configuration for the Cache.
         * 
         * The option is a: <code>javax.cache.configuration.Configuration</code>
         * type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder cacheConfiguration(
                Object cacheConfiguration) {
            doSetProperty("cacheConfiguration", cacheConfiguration);
            return this;
        }
        /**
         * A Configuration for the Cache.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Configuration</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder cacheConfiguration(
                String cacheConfiguration) {
            doSetProperty("cacheConfiguration", cacheConfiguration);
            return this;
        }
        /**
         * The Properties for the javax.cache.spi.CachingProvider to create the
         * CacheManager.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder cacheConfigurationProperties(
                Properties cacheConfigurationProperties) {
            doSetProperty("cacheConfigurationProperties", cacheConfigurationProperties);
            return this;
        }
        /**
         * The Properties for the javax.cache.spi.CachingProvider to create the
         * CacheManager.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder cacheConfigurationProperties(
                String cacheConfigurationProperties) {
            doSetProperty("cacheConfigurationProperties", cacheConfigurationProperties);
            return this;
        }
        /**
         * The fully qualified class name of the
         * javax.cache.spi.CachingProvider.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder cachingProvider(
                String cachingProvider) {
            doSetProperty("cachingProvider", cachingProvider);
            return this;
        }
        /**
         * An implementation specific URI for the CacheManager.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder configurationUri(
                String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * Whether management gathering is enabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder managementEnabled(
                boolean managementEnabled) {
            doSetProperty("managementEnabled", managementEnabled);
            return this;
        }
        /**
         * Whether management gathering is enabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder managementEnabled(
                String managementEnabled) {
            doSetProperty("managementEnabled", managementEnabled);
            return this;
        }
        /**
         * If read-through caching should be used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder readThrough(boolean readThrough) {
            doSetProperty("readThrough", readThrough);
            return this;
        }
        /**
         * If read-through caching should be used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder readThrough(String readThrough) {
            doSetProperty("readThrough", readThrough);
            return this;
        }
        /**
         * Whether statistics gathering is enabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder statisticsEnabled(
                boolean statisticsEnabled) {
            doSetProperty("statisticsEnabled", statisticsEnabled);
            return this;
        }
        /**
         * Whether statistics gathering is enabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder statisticsEnabled(
                String statisticsEnabled) {
            doSetProperty("statisticsEnabled", statisticsEnabled);
            return this;
        }
        /**
         * If cache should use store-by-value or store-by-reference semantics.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder storeByValue(boolean storeByValue) {
            doSetProperty("storeByValue", storeByValue);
            return this;
        }
        /**
         * If cache should use store-by-value or store-by-reference semantics.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder storeByValue(String storeByValue) {
            doSetProperty("storeByValue", storeByValue);
            return this;
        }
        /**
         * If write-through caching should be used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder writeThrough(boolean writeThrough) {
            doSetProperty("writeThrough", writeThrough);
            return this;
        }
        /**
         * If write-through caching should be used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointProducerBuilder writeThrough(String writeThrough) {
            doSetProperty("writeThrough", writeThrough);
            return this;
        }
        /**
         * To configure using a cache operation by default. If an operation in
         * the message header, then the operation from the header takes
         * precedence.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default JCacheEndpointProducerBuilder action(String action) {
            doSetProperty("action", action);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JCacheEndpointProducerBuilder lazyStartProducer(
                boolean lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * Whether the producer should be started lazy (on the first message).
         * By starting lazy you can use this to allow CamelContext and routes to
         * startup in situations where a producer may otherwise fail during
         * starting and cause the route to fail being started. By deferring this
         * startup to be lazy then the startup failure can be handled during
         * routing messages via Camel's routing error handlers. Beware that when
         * the first message is processed then creating and starting the
         * producer may take a little time and prolong the total processing time
         * of the processing.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default JCacheEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the JCache component.
     */
    public interface AdvancedJCacheEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default JCacheEndpointProducerBuilder basic() {
            return (JCacheEndpointProducerBuilder) this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * The CacheLoader factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheLoader&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder cacheLoaderFactory(
                Object cacheLoaderFactory) {
            doSetProperty("cacheLoaderFactory", cacheLoaderFactory);
            return this;
        }
        /**
         * The CacheLoader factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheLoader&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder cacheLoaderFactory(
                String cacheLoaderFactory) {
            doSetProperty("cacheLoaderFactory", cacheLoaderFactory);
            return this;
        }
        /**
         * The CacheWriter factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheWriter&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder cacheWriterFactory(
                Object cacheWriterFactory) {
            doSetProperty("cacheWriterFactory", cacheWriterFactory);
            return this;
        }
        /**
         * The CacheWriter factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheWriter&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder cacheWriterFactory(
                String cacheWriterFactory) {
            doSetProperty("cacheWriterFactory", cacheWriterFactory);
            return this;
        }
        /**
         * Configure if a cache need to be created if it does exist or can't be
         * pre-configured.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder createCacheIfNotExists(
                boolean createCacheIfNotExists) {
            doSetProperty("createCacheIfNotExists", createCacheIfNotExists);
            return this;
        }
        /**
         * Configure if a cache need to be created if it does exist or can't be
         * pre-configured.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder createCacheIfNotExists(
                String createCacheIfNotExists) {
            doSetProperty("createCacheIfNotExists", createCacheIfNotExists);
            return this;
        }
        /**
         * The ExpiryPolicy factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.expiry.ExpiryPolicy&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder expiryPolicyFactory(
                Object expiryPolicyFactory) {
            doSetProperty("expiryPolicyFactory", expiryPolicyFactory);
            return this;
        }
        /**
         * The ExpiryPolicy factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.expiry.ExpiryPolicy&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder expiryPolicyFactory(
                String expiryPolicyFactory) {
            doSetProperty("expiryPolicyFactory", expiryPolicyFactory);
            return this;
        }
        /**
         * Configure if a camel-cache should try to find implementations of
         * jcache api in runtimes like OSGi.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder lookupProviders(
                boolean lookupProviders) {
            doSetProperty("lookupProviders", lookupProviders);
            return this;
        }
        /**
         * Configure if a camel-cache should try to find implementations of
         * jcache api in runtimes like OSGi.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointProducerBuilder lookupProviders(
                String lookupProviders) {
            doSetProperty("lookupProviders", lookupProviders);
            return this;
        }
    }

    /**
     * Builder for endpoint for the JCache component.
     */
    public interface JCacheEndpointBuilder
            extends
                JCacheEndpointConsumerBuilder, JCacheEndpointProducerBuilder {
        default AdvancedJCacheEndpointBuilder advanced() {
            return (AdvancedJCacheEndpointBuilder) this;
        }
        /**
         * A Configuration for the Cache.
         * 
         * The option is a: <code>javax.cache.configuration.Configuration</code>
         * type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder cacheConfiguration(
                Object cacheConfiguration) {
            doSetProperty("cacheConfiguration", cacheConfiguration);
            return this;
        }
        /**
         * A Configuration for the Cache.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Configuration</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder cacheConfiguration(
                String cacheConfiguration) {
            doSetProperty("cacheConfiguration", cacheConfiguration);
            return this;
        }
        /**
         * The Properties for the javax.cache.spi.CachingProvider to create the
         * CacheManager.
         * 
         * The option is a: <code>java.util.Properties</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder cacheConfigurationProperties(
                Properties cacheConfigurationProperties) {
            doSetProperty("cacheConfigurationProperties", cacheConfigurationProperties);
            return this;
        }
        /**
         * The Properties for the javax.cache.spi.CachingProvider to create the
         * CacheManager.
         * 
         * The option will be converted to a <code>java.util.Properties</code>
         * type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder cacheConfigurationProperties(
                String cacheConfigurationProperties) {
            doSetProperty("cacheConfigurationProperties", cacheConfigurationProperties);
            return this;
        }
        /**
         * The fully qualified class name of the
         * javax.cache.spi.CachingProvider.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder cachingProvider(String cachingProvider) {
            doSetProperty("cachingProvider", cachingProvider);
            return this;
        }
        /**
         * An implementation specific URI for the CacheManager.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder configurationUri(String configurationUri) {
            doSetProperty("configurationUri", configurationUri);
            return this;
        }
        /**
         * Whether management gathering is enabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder managementEnabled(
                boolean managementEnabled) {
            doSetProperty("managementEnabled", managementEnabled);
            return this;
        }
        /**
         * Whether management gathering is enabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder managementEnabled(String managementEnabled) {
            doSetProperty("managementEnabled", managementEnabled);
            return this;
        }
        /**
         * If read-through caching should be used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder readThrough(boolean readThrough) {
            doSetProperty("readThrough", readThrough);
            return this;
        }
        /**
         * If read-through caching should be used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder readThrough(String readThrough) {
            doSetProperty("readThrough", readThrough);
            return this;
        }
        /**
         * Whether statistics gathering is enabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder statisticsEnabled(
                boolean statisticsEnabled) {
            doSetProperty("statisticsEnabled", statisticsEnabled);
            return this;
        }
        /**
         * Whether statistics gathering is enabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder statisticsEnabled(String statisticsEnabled) {
            doSetProperty("statisticsEnabled", statisticsEnabled);
            return this;
        }
        /**
         * If cache should use store-by-value or store-by-reference semantics.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder storeByValue(boolean storeByValue) {
            doSetProperty("storeByValue", storeByValue);
            return this;
        }
        /**
         * If cache should use store-by-value or store-by-reference semantics.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder storeByValue(String storeByValue) {
            doSetProperty("storeByValue", storeByValue);
            return this;
        }
        /**
         * If write-through caching should be used.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder writeThrough(boolean writeThrough) {
            doSetProperty("writeThrough", writeThrough);
            return this;
        }
        /**
         * If write-through caching should be used.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: common
         */
        default JCacheEndpointBuilder writeThrough(String writeThrough) {
            doSetProperty("writeThrough", writeThrough);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the JCache component.
     */
    public interface AdvancedJCacheEndpointBuilder
            extends
                AdvancedJCacheEndpointConsumerBuilder, AdvancedJCacheEndpointProducerBuilder {
        default JCacheEndpointBuilder basic() {
            return (JCacheEndpointBuilder) this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder basicPropertyBinding(
                boolean basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * Whether the endpoint should use basic property binding (Camel 2.x) or
         * the newer property binding with additional capabilities.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * The CacheLoader factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheLoader&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder cacheLoaderFactory(
                Object cacheLoaderFactory) {
            doSetProperty("cacheLoaderFactory", cacheLoaderFactory);
            return this;
        }
        /**
         * The CacheLoader factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheLoader&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder cacheLoaderFactory(
                String cacheLoaderFactory) {
            doSetProperty("cacheLoaderFactory", cacheLoaderFactory);
            return this;
        }
        /**
         * The CacheWriter factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheWriter&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder cacheWriterFactory(
                Object cacheWriterFactory) {
            doSetProperty("cacheWriterFactory", cacheWriterFactory);
            return this;
        }
        /**
         * The CacheWriter factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.integration.CacheWriter&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder cacheWriterFactory(
                String cacheWriterFactory) {
            doSetProperty("cacheWriterFactory", cacheWriterFactory);
            return this;
        }
        /**
         * Configure if a cache need to be created if it does exist or can't be
         * pre-configured.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder createCacheIfNotExists(
                boolean createCacheIfNotExists) {
            doSetProperty("createCacheIfNotExists", createCacheIfNotExists);
            return this;
        }
        /**
         * Configure if a cache need to be created if it does exist or can't be
         * pre-configured.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder createCacheIfNotExists(
                String createCacheIfNotExists) {
            doSetProperty("createCacheIfNotExists", createCacheIfNotExists);
            return this;
        }
        /**
         * The ExpiryPolicy factory.
         * 
         * The option is a:
         * <code>javax.cache.configuration.Factory&lt;javax.cache.expiry.ExpiryPolicy&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder expiryPolicyFactory(
                Object expiryPolicyFactory) {
            doSetProperty("expiryPolicyFactory", expiryPolicyFactory);
            return this;
        }
        /**
         * The ExpiryPolicy factory.
         * 
         * The option will be converted to a
         * <code>javax.cache.configuration.Factory&lt;javax.cache.expiry.ExpiryPolicy&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder expiryPolicyFactory(
                String expiryPolicyFactory) {
            doSetProperty("expiryPolicyFactory", expiryPolicyFactory);
            return this;
        }
        /**
         * Configure if a camel-cache should try to find implementations of
         * jcache api in runtimes like OSGi.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder lookupProviders(
                boolean lookupProviders) {
            doSetProperty("lookupProviders", lookupProviders);
            return this;
        }
        /**
         * Configure if a camel-cache should try to find implementations of
         * jcache api in runtimes like OSGi.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedJCacheEndpointBuilder lookupProviders(
                String lookupProviders) {
            doSetProperty("lookupProviders", lookupProviders);
            return this;
        }
    }

    /**
     * Proxy enum for <code>javax.cache.event.EventType</code> enum.
     */
    enum EventType {
        CREATED,
        UPDATED,
        REMOVED,
        EXPIRED;
    }
    /**
     * JCache (camel-jcache)
     * The jcache component enables you to perform caching operations using
     * JSR107/JCache as cache implementation.
     * 
     * Category: cache,datagrid,clustering
     * Since: 2.17
     * Maven coordinates: org.apache.camel:camel-jcache
     * 
     * Syntax: <code>jcache:cacheName</code>
     * 
     * Path parameter: cacheName (required)
     * The name of the cache
     */
    default JCacheEndpointBuilder jcache(String path) {
        class JCacheEndpointBuilderImpl extends AbstractEndpointBuilder implements JCacheEndpointBuilder, AdvancedJCacheEndpointBuilder {
            public JCacheEndpointBuilderImpl(String path) {
                super("jcache", path);
            }
        }
        return new JCacheEndpointBuilderImpl(path);
    }
}