/*
 * 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.Map;
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;
import org.apache.camel.spi.HeaderFilterStrategy;

/**
 * The cxf component is used for SOAP WebServices using Apache CXF.
 * 
 * Generated by camel-package-maven-plugin - do not edit this file!
 */
@Generated("org.apache.camel.maven.packaging.EndpointDslMojo")
public interface CxfEndpointBuilderFactory {


    /**
     * Builder for endpoint consumers for the CXF component.
     */
    public interface CxfEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default AdvancedCxfEndpointConsumerBuilder advanced() {
            return (AdvancedCxfEndpointConsumerBuilder) this;
        }
        /**
         * The data type messages supported by the CXF endpoint.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.DataFormat</code> type.
         * 
         * Group: common
         */
        default CxfEndpointConsumerBuilder dataFormat(DataFormat dataFormat) {
            doSetProperty("dataFormat", dataFormat);
            return this;
        }
        /**
         * The data type messages supported by the CXF endpoint.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.DataFormat</code> type.
         * 
         * Group: common
         */
        default CxfEndpointConsumerBuilder dataFormat(String dataFormat) {
            doSetProperty("dataFormat", dataFormat);
            return this;
        }
        /**
         * The WSDL style that describes how parameters are represented in the
         * SOAP body. If the value is false, CXF will chose the document-literal
         * unwrapped style, If the value is true, CXF will chose the
         * document-literal wrapped style.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: common
         */
        default CxfEndpointConsumerBuilder wrappedStyle(Boolean wrappedStyle) {
            doSetProperty("wrappedStyle", wrappedStyle);
            return this;
        }
        /**
         * The WSDL style that describes how parameters are represented in the
         * SOAP body. If the value is false, CXF will chose the document-literal
         * unwrapped style, If the value is true, CXF will chose the
         * document-literal wrapped style.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: common
         */
        default CxfEndpointConsumerBuilder wrappedStyle(String wrappedStyle) {
            doSetProperty("wrappedStyle", wrappedStyle);
            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 CxfEndpointConsumerBuilder 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 CxfEndpointConsumerBuilder bridgeErrorHandler(
                String bridgeErrorHandler) {
            doSetProperty("bridgeErrorHandler", bridgeErrorHandler);
            return this;
        }
        /**
         * This option enables CXF Logging Feature which writes inbound and
         * outbound SOAP messages to log.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointConsumerBuilder loggingFeatureEnabled(
                boolean loggingFeatureEnabled) {
            doSetProperty("loggingFeatureEnabled", loggingFeatureEnabled);
            return this;
        }
        /**
         * This option enables CXF Logging Feature which writes inbound and
         * outbound SOAP messages to log.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointConsumerBuilder loggingFeatureEnabled(
                String loggingFeatureEnabled) {
            doSetProperty("loggingFeatureEnabled", loggingFeatureEnabled);
            return this;
        }
        /**
         * To limit the total size of number of bytes the logger will output
         * when logging feature has been enabled and -1 for no limit.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointConsumerBuilder loggingSizeLimit(int loggingSizeLimit) {
            doSetProperty("loggingSizeLimit", loggingSizeLimit);
            return this;
        }
        /**
         * To limit the total size of number of bytes the logger will output
         * when logging feature has been enabled and -1 for no limit.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointConsumerBuilder loggingSizeLimit(
                String loggingSizeLimit) {
            doSetProperty("loggingSizeLimit", loggingSizeLimit);
            return this;
        }
        /**
         * This option controls whether the PhaseInterceptorChain skips logging
         * the Fault that it catches.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointConsumerBuilder skipFaultLogging(
                boolean skipFaultLogging) {
            doSetProperty("skipFaultLogging", skipFaultLogging);
            return this;
        }
        /**
         * This option controls whether the PhaseInterceptorChain skips logging
         * the Fault that it catches.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointConsumerBuilder skipFaultLogging(
                String skipFaultLogging) {
            doSetProperty("skipFaultLogging", skipFaultLogging);
            return this;
        }
        /**
         * This option is used to set the basic authentication information of
         * password for the CXF client.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default CxfEndpointConsumerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * This option is used to set the basic authentication information of
         * username for the CXF client.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default CxfEndpointConsumerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * The bindingId for the service model to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointConsumerBuilder bindingId(String bindingId) {
            doSetProperty("bindingId", bindingId);
            return this;
        }
        /**
         * The endpoint name this service is implementing, it maps to the
         * wsdl:portname. In the format of ns:PORT_NAME where ns is a namespace
         * prefix valid at this scope.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointConsumerBuilder portName(String portName) {
            doSetProperty("portName", portName);
            return this;
        }
        /**
         * This option can override the endpointUrl that published from the WSDL
         * which can be accessed with service address url plus wsd.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointConsumerBuilder publishedEndpointUrl(
                String publishedEndpointUrl) {
            doSetProperty("publishedEndpointUrl", publishedEndpointUrl);
            return this;
        }
        /**
         * The class name of the SEI (Service Endpoint Interface) class which
         * could have JSR181 annotation or not.
         * 
         * The option is a: <code>java.lang.Class&lt;java.lang.Object&gt;</code>
         * type.
         * 
         * Group: service
         */
        default CxfEndpointConsumerBuilder serviceClass(
                Class<Object> serviceClass) {
            doSetProperty("serviceClass", serviceClass);
            return this;
        }
        /**
         * The class name of the SEI (Service Endpoint Interface) class which
         * could have JSR181 annotation or not.
         * 
         * The option will be converted to a
         * <code>java.lang.Class&lt;java.lang.Object&gt;</code> type.
         * 
         * Group: service
         */
        default CxfEndpointConsumerBuilder serviceClass(String serviceClass) {
            doSetProperty("serviceClass", serviceClass);
            return this;
        }
        /**
         * The service name this service is implementing, it maps to the
         * wsdl:servicename.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointConsumerBuilder serviceName(String serviceName) {
            doSetProperty("serviceName", serviceName);
            return this;
        }
        /**
         * The location of the WSDL. Can be on the classpath, file system, or be
         * hosted remotely.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointConsumerBuilder wsdlURL(String wsdlURL) {
            doSetProperty("wsdlURL", wsdlURL);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint consumers for the CXF component.
     */
    public interface AdvancedCxfEndpointConsumerBuilder
            extends
                EndpointConsumerBuilder {
        default CxfEndpointConsumerBuilder basic() {
            return (CxfEndpointConsumerBuilder) 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 AdvancedCxfEndpointConsumerBuilder 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 AdvancedCxfEndpointConsumerBuilder 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 AdvancedCxfEndpointConsumerBuilder 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 AdvancedCxfEndpointConsumerBuilder exchangePattern(
                String exchangePattern) {
            doSetProperty("exchangePattern", exchangePattern);
            return this;
        }
        /**
         * This option controls whether the CXF component, when running in
         * PAYLOAD mode, will DOM parse the incoming messages into DOM Elements
         * or keep the payload as a javax.xml.transform.Source object that would
         * allow streaming in some cases.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder allowStreaming(
                Boolean allowStreaming) {
            doSetProperty("allowStreaming", allowStreaming);
            return this;
        }
        /**
         * This option controls whether the CXF component, when running in
         * PAYLOAD mode, will DOM parse the incoming messages into DOM Elements
         * or keep the payload as a javax.xml.transform.Source object that would
         * allow streaming in some cases.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder allowStreaming(
                String allowStreaming) {
            doSetProperty("allowStreaming", allowStreaming);
            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 AdvancedCxfEndpointConsumerBuilder 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 AdvancedCxfEndpointConsumerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * To use a custom configured CXF Bus.
         * 
         * The option is a: <code>org.apache.cxf.Bus</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder bus(Object bus) {
            doSetProperty("bus", bus);
            return this;
        }
        /**
         * To use a custom configured CXF Bus.
         * 
         * The option will be converted to a <code>org.apache.cxf.Bus</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder bus(String bus) {
            doSetProperty("bus", bus);
            return this;
        }
        /**
         * This option is used to set the CXF continuation timeout which could
         * be used in CxfConsumer by default when the CXF server is using Jetty
         * or Servlet transport.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder continuationTimeout(
                long continuationTimeout) {
            doSetProperty("continuationTimeout", continuationTimeout);
            return this;
        }
        /**
         * This option is used to set the CXF continuation timeout which could
         * be used in CxfConsumer by default when the CXF server is using Jetty
         * or Servlet transport.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder continuationTimeout(
                String continuationTimeout) {
            doSetProperty("continuationTimeout", continuationTimeout);
            return this;
        }
        /**
         * To use a custom CxfBinding to control the binding between Camel
         * Message and CXF Message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.CxfBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder cxfBinding(Object cxfBinding) {
            doSetProperty("cxfBinding", cxfBinding);
            return this;
        }
        /**
         * To use a custom CxfBinding to control the binding between Camel
         * Message and CXF Message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.CxfBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder cxfBinding(String cxfBinding) {
            doSetProperty("cxfBinding", cxfBinding);
            return this;
        }
        /**
         * This option could apply the implementation of
         * org.apache.camel.component.cxf.CxfEndpointConfigurer which supports
         * to configure the CXF endpoint in programmatic way. User can configure
         * the CXF server and client by implementing configure{ServerClient}
         * method of CxfEndpointConfigurer.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.CxfConfigurer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder cxfConfigurer(
                Object cxfConfigurer) {
            doSetProperty("cxfConfigurer", cxfConfigurer);
            return this;
        }
        /**
         * This option could apply the implementation of
         * org.apache.camel.component.cxf.CxfEndpointConfigurer which supports
         * to configure the CXF endpoint in programmatic way. User can configure
         * the CXF server and client by implementing configure{ServerClient}
         * method of CxfEndpointConfigurer.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.CxfConfigurer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder cxfConfigurer(
                String cxfConfigurer) {
            doSetProperty("cxfConfigurer", cxfConfigurer);
            return this;
        }
        /**
         * Will set the default bus when CXF endpoint create a bus by itself.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder defaultBus(boolean defaultBus) {
            doSetProperty("defaultBus", defaultBus);
            return this;
        }
        /**
         * Will set the default bus when CXF endpoint create a bus by itself.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder defaultBus(String defaultBus) {
            doSetProperty("defaultBus", defaultBus);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Whether to merge protocol headers. If enabled then propagating
         * headers between Camel and CXF becomes more consistent and similar.
         * For more details see CAMEL-6393.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder mergeProtocolHeaders(
                boolean mergeProtocolHeaders) {
            doSetProperty("mergeProtocolHeaders", mergeProtocolHeaders);
            return this;
        }
        /**
         * Whether to merge protocol headers. If enabled then propagating
         * headers between Camel and CXF becomes more consistent and similar.
         * For more details see CAMEL-6393.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder mergeProtocolHeaders(
                String mergeProtocolHeaders) {
            doSetProperty("mergeProtocolHeaders", mergeProtocolHeaders);
            return this;
        }
        /**
         * To enable MTOM (attachments). This requires to use POJO or PAYLOAD
         * data format mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder mtomEnabled(
                boolean mtomEnabled) {
            doSetProperty("mtomEnabled", mtomEnabled);
            return this;
        }
        /**
         * To enable MTOM (attachments). This requires to use POJO or PAYLOAD
         * data format mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder mtomEnabled(
                String mtomEnabled) {
            doSetProperty("mtomEnabled", mtomEnabled);
            return this;
        }
        /**
         * To set additional CXF options using the key/value pairs from the Map.
         * For example to turn on stacktraces in SOAP faults,
         * properties.faultStackTraceEnabled=true.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder properties(
                Map<String, Object> properties) {
            doSetProperty("properties", properties);
            return this;
        }
        /**
         * To set additional CXF options using the key/value pairs from the Map.
         * For example to turn on stacktraces in SOAP faults,
         * properties.faultStackTraceEnabled=true.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder properties(String properties) {
            doSetProperty("properties", properties);
            return this;
        }
        /**
         * Sets whether SOAP message validation should be disabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder skipPayloadMessagePartCheck(
                boolean skipPayloadMessagePartCheck) {
            doSetProperty("skipPayloadMessagePartCheck", skipPayloadMessagePartCheck);
            return this;
        }
        /**
         * Sets whether SOAP message validation should be disabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder skipPayloadMessagePartCheck(
                String skipPayloadMessagePartCheck) {
            doSetProperty("skipPayloadMessagePartCheck", skipPayloadMessagePartCheck);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointConsumerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint producers for the CXF component.
     */
    public interface CxfEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default AdvancedCxfEndpointProducerBuilder advanced() {
            return (AdvancedCxfEndpointProducerBuilder) this;
        }
        /**
         * The data type messages supported by the CXF endpoint.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.DataFormat</code> type.
         * 
         * Group: common
         */
        default CxfEndpointProducerBuilder dataFormat(DataFormat dataFormat) {
            doSetProperty("dataFormat", dataFormat);
            return this;
        }
        /**
         * The data type messages supported by the CXF endpoint.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.DataFormat</code> type.
         * 
         * Group: common
         */
        default CxfEndpointProducerBuilder dataFormat(String dataFormat) {
            doSetProperty("dataFormat", dataFormat);
            return this;
        }
        /**
         * The WSDL style that describes how parameters are represented in the
         * SOAP body. If the value is false, CXF will chose the document-literal
         * unwrapped style, If the value is true, CXF will chose the
         * document-literal wrapped style.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: common
         */
        default CxfEndpointProducerBuilder wrappedStyle(Boolean wrappedStyle) {
            doSetProperty("wrappedStyle", wrappedStyle);
            return this;
        }
        /**
         * The WSDL style that describes how parameters are represented in the
         * SOAP body. If the value is false, CXF will chose the document-literal
         * unwrapped style, If the value is true, CXF will chose the
         * document-literal wrapped style.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: common
         */
        default CxfEndpointProducerBuilder wrappedStyle(String wrappedStyle) {
            doSetProperty("wrappedStyle", wrappedStyle);
            return this;
        }
        /**
         * Configure a cookie handler to maintain a HTTP session.
         * 
         * The option is a:
         * <code>org.apache.camel.http.common.cookie.CookieHandler</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder cookieHandler(Object cookieHandler) {
            doSetProperty("cookieHandler", cookieHandler);
            return this;
        }
        /**
         * Configure a cookie handler to maintain a HTTP session.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.http.common.cookie.CookieHandler</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder cookieHandler(String cookieHandler) {
            doSetProperty("cookieHandler", cookieHandler);
            return this;
        }
        /**
         * This option will set the default operationName that will be used by
         * the CxfProducer which invokes the remote service.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder defaultOperationName(
                String defaultOperationName) {
            doSetProperty("defaultOperationName", defaultOperationName);
            return this;
        }
        /**
         * This option will set the default operationNamespace that will be used
         * by the CxfProducer which invokes the remote service.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder defaultOperationNamespace(
                String defaultOperationNamespace) {
            doSetProperty("defaultOperationNamespace", defaultOperationNamespace);
            return this;
        }
        /**
         * The hostname verifier to be used. Use the # notation to reference a
         * HostnameVerifier from the registry.
         * 
         * The option is a: <code>javax.net.ssl.HostnameVerifier</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder hostnameVerifier(
                Object hostnameVerifier) {
            doSetProperty("hostnameVerifier", hostnameVerifier);
            return this;
        }
        /**
         * The hostname verifier to be used. Use the # notation to reference a
         * HostnameVerifier from the registry.
         * 
         * The option will be converted to a
         * <code>javax.net.ssl.HostnameVerifier</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder hostnameVerifier(
                String hostnameVerifier) {
            doSetProperty("hostnameVerifier", hostnameVerifier);
            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 CxfEndpointProducerBuilder 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 CxfEndpointProducerBuilder lazyStartProducer(
                String lazyStartProducer) {
            doSetProperty("lazyStartProducer", lazyStartProducer);
            return this;
        }
        /**
         * The Camel SSL setting reference. Use the # notation to reference the
         * SSL Context.
         * 
         * The option is a:
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder sslContextParameters(
                Object sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * The Camel SSL setting reference. Use the # notation to reference the
         * SSL Context.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.support.jsse.SSLContextParameters</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder sslContextParameters(
                String sslContextParameters) {
            doSetProperty("sslContextParameters", sslContextParameters);
            return this;
        }
        /**
         * Which kind of operation that CXF endpoint producer will invoke.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder wrapped(boolean wrapped) {
            doSetProperty("wrapped", wrapped);
            return this;
        }
        /**
         * Which kind of operation that CXF endpoint producer will invoke.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: producer
         */
        default CxfEndpointProducerBuilder wrapped(String wrapped) {
            doSetProperty("wrapped", wrapped);
            return this;
        }
        /**
         * This option enables CXF Logging Feature which writes inbound and
         * outbound SOAP messages to log.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointProducerBuilder loggingFeatureEnabled(
                boolean loggingFeatureEnabled) {
            doSetProperty("loggingFeatureEnabled", loggingFeatureEnabled);
            return this;
        }
        /**
         * This option enables CXF Logging Feature which writes inbound and
         * outbound SOAP messages to log.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointProducerBuilder loggingFeatureEnabled(
                String loggingFeatureEnabled) {
            doSetProperty("loggingFeatureEnabled", loggingFeatureEnabled);
            return this;
        }
        /**
         * To limit the total size of number of bytes the logger will output
         * when logging feature has been enabled and -1 for no limit.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointProducerBuilder loggingSizeLimit(int loggingSizeLimit) {
            doSetProperty("loggingSizeLimit", loggingSizeLimit);
            return this;
        }
        /**
         * To limit the total size of number of bytes the logger will output
         * when logging feature has been enabled and -1 for no limit.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointProducerBuilder loggingSizeLimit(
                String loggingSizeLimit) {
            doSetProperty("loggingSizeLimit", loggingSizeLimit);
            return this;
        }
        /**
         * This option controls whether the PhaseInterceptorChain skips logging
         * the Fault that it catches.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointProducerBuilder skipFaultLogging(
                boolean skipFaultLogging) {
            doSetProperty("skipFaultLogging", skipFaultLogging);
            return this;
        }
        /**
         * This option controls whether the PhaseInterceptorChain skips logging
         * the Fault that it catches.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointProducerBuilder skipFaultLogging(
                String skipFaultLogging) {
            doSetProperty("skipFaultLogging", skipFaultLogging);
            return this;
        }
        /**
         * This option is used to set the basic authentication information of
         * password for the CXF client.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default CxfEndpointProducerBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * This option is used to set the basic authentication information of
         * username for the CXF client.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default CxfEndpointProducerBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * The bindingId for the service model to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointProducerBuilder bindingId(String bindingId) {
            doSetProperty("bindingId", bindingId);
            return this;
        }
        /**
         * The endpoint name this service is implementing, it maps to the
         * wsdl:portname. In the format of ns:PORT_NAME where ns is a namespace
         * prefix valid at this scope.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointProducerBuilder portName(String portName) {
            doSetProperty("portName", portName);
            return this;
        }
        /**
         * This option can override the endpointUrl that published from the WSDL
         * which can be accessed with service address url plus wsd.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointProducerBuilder publishedEndpointUrl(
                String publishedEndpointUrl) {
            doSetProperty("publishedEndpointUrl", publishedEndpointUrl);
            return this;
        }
        /**
         * The class name of the SEI (Service Endpoint Interface) class which
         * could have JSR181 annotation or not.
         * 
         * The option is a: <code>java.lang.Class&lt;java.lang.Object&gt;</code>
         * type.
         * 
         * Group: service
         */
        default CxfEndpointProducerBuilder serviceClass(
                Class<Object> serviceClass) {
            doSetProperty("serviceClass", serviceClass);
            return this;
        }
        /**
         * The class name of the SEI (Service Endpoint Interface) class which
         * could have JSR181 annotation or not.
         * 
         * The option will be converted to a
         * <code>java.lang.Class&lt;java.lang.Object&gt;</code> type.
         * 
         * Group: service
         */
        default CxfEndpointProducerBuilder serviceClass(String serviceClass) {
            doSetProperty("serviceClass", serviceClass);
            return this;
        }
        /**
         * The service name this service is implementing, it maps to the
         * wsdl:servicename.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointProducerBuilder serviceName(String serviceName) {
            doSetProperty("serviceName", serviceName);
            return this;
        }
        /**
         * The location of the WSDL. Can be on the classpath, file system, or be
         * hosted remotely.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointProducerBuilder wsdlURL(String wsdlURL) {
            doSetProperty("wsdlURL", wsdlURL);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint producers for the CXF component.
     */
    public interface AdvancedCxfEndpointProducerBuilder
            extends
                EndpointProducerBuilder {
        default CxfEndpointProducerBuilder basic() {
            return (CxfEndpointProducerBuilder) this;
        }
        /**
         * This option controls whether the CXF component, when running in
         * PAYLOAD mode, will DOM parse the incoming messages into DOM Elements
         * or keep the payload as a javax.xml.transform.Source object that would
         * allow streaming in some cases.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder allowStreaming(
                Boolean allowStreaming) {
            doSetProperty("allowStreaming", allowStreaming);
            return this;
        }
        /**
         * This option controls whether the CXF component, when running in
         * PAYLOAD mode, will DOM parse the incoming messages into DOM Elements
         * or keep the payload as a javax.xml.transform.Source object that would
         * allow streaming in some cases.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder allowStreaming(
                String allowStreaming) {
            doSetProperty("allowStreaming", allowStreaming);
            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 AdvancedCxfEndpointProducerBuilder 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 AdvancedCxfEndpointProducerBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * To use a custom configured CXF Bus.
         * 
         * The option is a: <code>org.apache.cxf.Bus</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder bus(Object bus) {
            doSetProperty("bus", bus);
            return this;
        }
        /**
         * To use a custom configured CXF Bus.
         * 
         * The option will be converted to a <code>org.apache.cxf.Bus</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder bus(String bus) {
            doSetProperty("bus", bus);
            return this;
        }
        /**
         * This option is used to set the CXF continuation timeout which could
         * be used in CxfConsumer by default when the CXF server is using Jetty
         * or Servlet transport.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder continuationTimeout(
                long continuationTimeout) {
            doSetProperty("continuationTimeout", continuationTimeout);
            return this;
        }
        /**
         * This option is used to set the CXF continuation timeout which could
         * be used in CxfConsumer by default when the CXF server is using Jetty
         * or Servlet transport.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder continuationTimeout(
                String continuationTimeout) {
            doSetProperty("continuationTimeout", continuationTimeout);
            return this;
        }
        /**
         * To use a custom CxfBinding to control the binding between Camel
         * Message and CXF Message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.CxfBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder cxfBinding(Object cxfBinding) {
            doSetProperty("cxfBinding", cxfBinding);
            return this;
        }
        /**
         * To use a custom CxfBinding to control the binding between Camel
         * Message and CXF Message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.CxfBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder cxfBinding(String cxfBinding) {
            doSetProperty("cxfBinding", cxfBinding);
            return this;
        }
        /**
         * This option could apply the implementation of
         * org.apache.camel.component.cxf.CxfEndpointConfigurer which supports
         * to configure the CXF endpoint in programmatic way. User can configure
         * the CXF server and client by implementing configure{ServerClient}
         * method of CxfEndpointConfigurer.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.CxfConfigurer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder cxfConfigurer(
                Object cxfConfigurer) {
            doSetProperty("cxfConfigurer", cxfConfigurer);
            return this;
        }
        /**
         * This option could apply the implementation of
         * org.apache.camel.component.cxf.CxfEndpointConfigurer which supports
         * to configure the CXF endpoint in programmatic way. User can configure
         * the CXF server and client by implementing configure{ServerClient}
         * method of CxfEndpointConfigurer.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.CxfConfigurer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder cxfConfigurer(
                String cxfConfigurer) {
            doSetProperty("cxfConfigurer", cxfConfigurer);
            return this;
        }
        /**
         * Will set the default bus when CXF endpoint create a bus by itself.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder defaultBus(boolean defaultBus) {
            doSetProperty("defaultBus", defaultBus);
            return this;
        }
        /**
         * Will set the default bus when CXF endpoint create a bus by itself.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder defaultBus(String defaultBus) {
            doSetProperty("defaultBus", defaultBus);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Whether to merge protocol headers. If enabled then propagating
         * headers between Camel and CXF becomes more consistent and similar.
         * For more details see CAMEL-6393.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder mergeProtocolHeaders(
                boolean mergeProtocolHeaders) {
            doSetProperty("mergeProtocolHeaders", mergeProtocolHeaders);
            return this;
        }
        /**
         * Whether to merge protocol headers. If enabled then propagating
         * headers between Camel and CXF becomes more consistent and similar.
         * For more details see CAMEL-6393.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder mergeProtocolHeaders(
                String mergeProtocolHeaders) {
            doSetProperty("mergeProtocolHeaders", mergeProtocolHeaders);
            return this;
        }
        /**
         * To enable MTOM (attachments). This requires to use POJO or PAYLOAD
         * data format mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder mtomEnabled(
                boolean mtomEnabled) {
            doSetProperty("mtomEnabled", mtomEnabled);
            return this;
        }
        /**
         * To enable MTOM (attachments). This requires to use POJO or PAYLOAD
         * data format mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder mtomEnabled(
                String mtomEnabled) {
            doSetProperty("mtomEnabled", mtomEnabled);
            return this;
        }
        /**
         * To set additional CXF options using the key/value pairs from the Map.
         * For example to turn on stacktraces in SOAP faults,
         * properties.faultStackTraceEnabled=true.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder properties(
                Map<String, Object> properties) {
            doSetProperty("properties", properties);
            return this;
        }
        /**
         * To set additional CXF options using the key/value pairs from the Map.
         * For example to turn on stacktraces in SOAP faults,
         * properties.faultStackTraceEnabled=true.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder properties(String properties) {
            doSetProperty("properties", properties);
            return this;
        }
        /**
         * Sets whether SOAP message validation should be disabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder skipPayloadMessagePartCheck(
                boolean skipPayloadMessagePartCheck) {
            doSetProperty("skipPayloadMessagePartCheck", skipPayloadMessagePartCheck);
            return this;
        }
        /**
         * Sets whether SOAP message validation should be disabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder skipPayloadMessagePartCheck(
                String skipPayloadMessagePartCheck) {
            doSetProperty("skipPayloadMessagePartCheck", skipPayloadMessagePartCheck);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder synchronous(
                boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointProducerBuilder synchronous(
                String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Builder for endpoint for the CXF component.
     */
    public interface CxfEndpointBuilder
            extends
                CxfEndpointConsumerBuilder, CxfEndpointProducerBuilder {
        default AdvancedCxfEndpointBuilder advanced() {
            return (AdvancedCxfEndpointBuilder) this;
        }
        /**
         * The data type messages supported by the CXF endpoint.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.DataFormat</code> type.
         * 
         * Group: common
         */
        default CxfEndpointBuilder dataFormat(DataFormat dataFormat) {
            doSetProperty("dataFormat", dataFormat);
            return this;
        }
        /**
         * The data type messages supported by the CXF endpoint.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.DataFormat</code> type.
         * 
         * Group: common
         */
        default CxfEndpointBuilder dataFormat(String dataFormat) {
            doSetProperty("dataFormat", dataFormat);
            return this;
        }
        /**
         * The WSDL style that describes how parameters are represented in the
         * SOAP body. If the value is false, CXF will chose the document-literal
         * unwrapped style, If the value is true, CXF will chose the
         * document-literal wrapped style.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: common
         */
        default CxfEndpointBuilder wrappedStyle(Boolean wrappedStyle) {
            doSetProperty("wrappedStyle", wrappedStyle);
            return this;
        }
        /**
         * The WSDL style that describes how parameters are represented in the
         * SOAP body. If the value is false, CXF will chose the document-literal
         * unwrapped style, If the value is true, CXF will chose the
         * document-literal wrapped style.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: common
         */
        default CxfEndpointBuilder wrappedStyle(String wrappedStyle) {
            doSetProperty("wrappedStyle", wrappedStyle);
            return this;
        }
        /**
         * This option enables CXF Logging Feature which writes inbound and
         * outbound SOAP messages to log.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointBuilder loggingFeatureEnabled(
                boolean loggingFeatureEnabled) {
            doSetProperty("loggingFeatureEnabled", loggingFeatureEnabled);
            return this;
        }
        /**
         * This option enables CXF Logging Feature which writes inbound and
         * outbound SOAP messages to log.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointBuilder loggingFeatureEnabled(
                String loggingFeatureEnabled) {
            doSetProperty("loggingFeatureEnabled", loggingFeatureEnabled);
            return this;
        }
        /**
         * To limit the total size of number of bytes the logger will output
         * when logging feature has been enabled and -1 for no limit.
         * 
         * The option is a: <code>int</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointBuilder loggingSizeLimit(int loggingSizeLimit) {
            doSetProperty("loggingSizeLimit", loggingSizeLimit);
            return this;
        }
        /**
         * To limit the total size of number of bytes the logger will output
         * when logging feature has been enabled and -1 for no limit.
         * 
         * The option will be converted to a <code>int</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointBuilder loggingSizeLimit(String loggingSizeLimit) {
            doSetProperty("loggingSizeLimit", loggingSizeLimit);
            return this;
        }
        /**
         * This option controls whether the PhaseInterceptorChain skips logging
         * the Fault that it catches.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointBuilder skipFaultLogging(boolean skipFaultLogging) {
            doSetProperty("skipFaultLogging", skipFaultLogging);
            return this;
        }
        /**
         * This option controls whether the PhaseInterceptorChain skips logging
         * the Fault that it catches.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: logging
         */
        default CxfEndpointBuilder skipFaultLogging(String skipFaultLogging) {
            doSetProperty("skipFaultLogging", skipFaultLogging);
            return this;
        }
        /**
         * This option is used to set the basic authentication information of
         * password for the CXF client.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default CxfEndpointBuilder password(String password) {
            doSetProperty("password", password);
            return this;
        }
        /**
         * This option is used to set the basic authentication information of
         * username for the CXF client.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: security
         */
        default CxfEndpointBuilder username(String username) {
            doSetProperty("username", username);
            return this;
        }
        /**
         * The bindingId for the service model to use.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointBuilder bindingId(String bindingId) {
            doSetProperty("bindingId", bindingId);
            return this;
        }
        /**
         * The endpoint name this service is implementing, it maps to the
         * wsdl:portname. In the format of ns:PORT_NAME where ns is a namespace
         * prefix valid at this scope.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointBuilder portName(String portName) {
            doSetProperty("portName", portName);
            return this;
        }
        /**
         * This option can override the endpointUrl that published from the WSDL
         * which can be accessed with service address url plus wsd.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointBuilder publishedEndpointUrl(
                String publishedEndpointUrl) {
            doSetProperty("publishedEndpointUrl", publishedEndpointUrl);
            return this;
        }
        /**
         * The class name of the SEI (Service Endpoint Interface) class which
         * could have JSR181 annotation or not.
         * 
         * The option is a: <code>java.lang.Class&lt;java.lang.Object&gt;</code>
         * type.
         * 
         * Group: service
         */
        default CxfEndpointBuilder serviceClass(Class<Object> serviceClass) {
            doSetProperty("serviceClass", serviceClass);
            return this;
        }
        /**
         * The class name of the SEI (Service Endpoint Interface) class which
         * could have JSR181 annotation or not.
         * 
         * The option will be converted to a
         * <code>java.lang.Class&lt;java.lang.Object&gt;</code> type.
         * 
         * Group: service
         */
        default CxfEndpointBuilder serviceClass(String serviceClass) {
            doSetProperty("serviceClass", serviceClass);
            return this;
        }
        /**
         * The service name this service is implementing, it maps to the
         * wsdl:servicename.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointBuilder serviceName(String serviceName) {
            doSetProperty("serviceName", serviceName);
            return this;
        }
        /**
         * The location of the WSDL. Can be on the classpath, file system, or be
         * hosted remotely.
         * 
         * The option is a: <code>java.lang.String</code> type.
         * 
         * Group: service
         */
        default CxfEndpointBuilder wsdlURL(String wsdlURL) {
            doSetProperty("wsdlURL", wsdlURL);
            return this;
        }
    }

    /**
     * Advanced builder for endpoint for the CXF component.
     */
    public interface AdvancedCxfEndpointBuilder
            extends
                AdvancedCxfEndpointConsumerBuilder, AdvancedCxfEndpointProducerBuilder {
        default CxfEndpointBuilder basic() {
            return (CxfEndpointBuilder) this;
        }
        /**
         * This option controls whether the CXF component, when running in
         * PAYLOAD mode, will DOM parse the incoming messages into DOM Elements
         * or keep the payload as a javax.xml.transform.Source object that would
         * allow streaming in some cases.
         * 
         * The option is a: <code>java.lang.Boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder allowStreaming(Boolean allowStreaming) {
            doSetProperty("allowStreaming", allowStreaming);
            return this;
        }
        /**
         * This option controls whether the CXF component, when running in
         * PAYLOAD mode, will DOM parse the incoming messages into DOM Elements
         * or keep the payload as a javax.xml.transform.Source object that would
         * allow streaming in some cases.
         * 
         * The option will be converted to a <code>java.lang.Boolean</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder allowStreaming(String allowStreaming) {
            doSetProperty("allowStreaming", allowStreaming);
            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 AdvancedCxfEndpointBuilder 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 AdvancedCxfEndpointBuilder basicPropertyBinding(
                String basicPropertyBinding) {
            doSetProperty("basicPropertyBinding", basicPropertyBinding);
            return this;
        }
        /**
         * To use a custom configured CXF Bus.
         * 
         * The option is a: <code>org.apache.cxf.Bus</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder bus(Object bus) {
            doSetProperty("bus", bus);
            return this;
        }
        /**
         * To use a custom configured CXF Bus.
         * 
         * The option will be converted to a <code>org.apache.cxf.Bus</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder bus(String bus) {
            doSetProperty("bus", bus);
            return this;
        }
        /**
         * This option is used to set the CXF continuation timeout which could
         * be used in CxfConsumer by default when the CXF server is using Jetty
         * or Servlet transport.
         * 
         * The option is a: <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder continuationTimeout(
                long continuationTimeout) {
            doSetProperty("continuationTimeout", continuationTimeout);
            return this;
        }
        /**
         * This option is used to set the CXF continuation timeout which could
         * be used in CxfConsumer by default when the CXF server is using Jetty
         * or Servlet transport.
         * 
         * The option will be converted to a <code>long</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder continuationTimeout(
                String continuationTimeout) {
            doSetProperty("continuationTimeout", continuationTimeout);
            return this;
        }
        /**
         * To use a custom CxfBinding to control the binding between Camel
         * Message and CXF Message.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.CxfBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder cxfBinding(Object cxfBinding) {
            doSetProperty("cxfBinding", cxfBinding);
            return this;
        }
        /**
         * To use a custom CxfBinding to control the binding between Camel
         * Message and CXF Message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.CxfBinding</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder cxfBinding(String cxfBinding) {
            doSetProperty("cxfBinding", cxfBinding);
            return this;
        }
        /**
         * This option could apply the implementation of
         * org.apache.camel.component.cxf.CxfEndpointConfigurer which supports
         * to configure the CXF endpoint in programmatic way. User can configure
         * the CXF server and client by implementing configure{ServerClient}
         * method of CxfEndpointConfigurer.
         * 
         * The option is a:
         * <code>org.apache.camel.component.cxf.CxfConfigurer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder cxfConfigurer(Object cxfConfigurer) {
            doSetProperty("cxfConfigurer", cxfConfigurer);
            return this;
        }
        /**
         * This option could apply the implementation of
         * org.apache.camel.component.cxf.CxfEndpointConfigurer which supports
         * to configure the CXF endpoint in programmatic way. User can configure
         * the CXF server and client by implementing configure{ServerClient}
         * method of CxfEndpointConfigurer.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.component.cxf.CxfConfigurer</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder cxfConfigurer(String cxfConfigurer) {
            doSetProperty("cxfConfigurer", cxfConfigurer);
            return this;
        }
        /**
         * Will set the default bus when CXF endpoint create a bus by itself.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder defaultBus(boolean defaultBus) {
            doSetProperty("defaultBus", defaultBus);
            return this;
        }
        /**
         * Will set the default bus when CXF endpoint create a bus by itself.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder defaultBus(String defaultBus) {
            doSetProperty("defaultBus", defaultBus);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option is a:
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder headerFilterStrategy(
                HeaderFilterStrategy headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * To use a custom HeaderFilterStrategy to filter header to and from
         * Camel message.
         * 
         * The option will be converted to a
         * <code>org.apache.camel.spi.HeaderFilterStrategy</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder headerFilterStrategy(
                String headerFilterStrategy) {
            doSetProperty("headerFilterStrategy", headerFilterStrategy);
            return this;
        }
        /**
         * Whether to merge protocol headers. If enabled then propagating
         * headers between Camel and CXF becomes more consistent and similar.
         * For more details see CAMEL-6393.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder mergeProtocolHeaders(
                boolean mergeProtocolHeaders) {
            doSetProperty("mergeProtocolHeaders", mergeProtocolHeaders);
            return this;
        }
        /**
         * Whether to merge protocol headers. If enabled then propagating
         * headers between Camel and CXF becomes more consistent and similar.
         * For more details see CAMEL-6393.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder mergeProtocolHeaders(
                String mergeProtocolHeaders) {
            doSetProperty("mergeProtocolHeaders", mergeProtocolHeaders);
            return this;
        }
        /**
         * To enable MTOM (attachments). This requires to use POJO or PAYLOAD
         * data format mode.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder mtomEnabled(boolean mtomEnabled) {
            doSetProperty("mtomEnabled", mtomEnabled);
            return this;
        }
        /**
         * To enable MTOM (attachments). This requires to use POJO or PAYLOAD
         * data format mode.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder mtomEnabled(String mtomEnabled) {
            doSetProperty("mtomEnabled", mtomEnabled);
            return this;
        }
        /**
         * To set additional CXF options using the key/value pairs from the Map.
         * For example to turn on stacktraces in SOAP faults,
         * properties.faultStackTraceEnabled=true.
         * 
         * The option is a: <code>java.util.Map&lt;java.lang.String,
         * java.lang.Object&gt;</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder properties(
                Map<String, Object> properties) {
            doSetProperty("properties", properties);
            return this;
        }
        /**
         * To set additional CXF options using the key/value pairs from the Map.
         * For example to turn on stacktraces in SOAP faults,
         * properties.faultStackTraceEnabled=true.
         * 
         * The option will be converted to a
         * <code>java.util.Map&lt;java.lang.String, java.lang.Object&gt;</code>
         * type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder properties(String properties) {
            doSetProperty("properties", properties);
            return this;
        }
        /**
         * Sets whether SOAP message validation should be disabled.
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder skipPayloadMessagePartCheck(
                boolean skipPayloadMessagePartCheck) {
            doSetProperty("skipPayloadMessagePartCheck", skipPayloadMessagePartCheck);
            return this;
        }
        /**
         * Sets whether SOAP message validation should be disabled.
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder skipPayloadMessagePartCheck(
                String skipPayloadMessagePartCheck) {
            doSetProperty("skipPayloadMessagePartCheck", skipPayloadMessagePartCheck);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option is a: <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder synchronous(boolean synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
        /**
         * Sets whether synchronous processing should be strictly used, or Camel
         * is allowed to use asynchronous processing (if supported).
         * 
         * The option will be converted to a <code>boolean</code> type.
         * 
         * Group: advanced
         */
        default AdvancedCxfEndpointBuilder synchronous(String synchronous) {
            doSetProperty("synchronous", synchronous);
            return this;
        }
    }

    /**
     * Proxy enum for <code>org.apache.camel.component.cxf.DataFormat</code>
     * enum.
     */
    enum DataFormat {
        PAYLOAD,
        RAW,
        MESSAGE,
        CXF_MESSAGE,
        POJO;
    }
    /**
     * CXF (camel-cxf)
     * The cxf component is used for SOAP WebServices using Apache CXF.
     * 
     * Category: soap,webservice
     * Since: 1.0
     * Maven coordinates: org.apache.camel:camel-cxf
     * 
     * Syntax: <code>cxf:beanId:address</code>
     * 
     * Path parameter: beanId
     * To lookup an existing configured CxfEndpoint. Must used bean: as prefix.
     * 
     * Path parameter: address
     * The service publish address.
     */
    default CxfEndpointBuilder cxf(String path) {
        class CxfEndpointBuilderImpl extends AbstractEndpointBuilder implements CxfEndpointBuilder, AdvancedCxfEndpointBuilder {
            public CxfEndpointBuilderImpl(String path) {
                super("cxf", path);
            }
        }
        return new CxfEndpointBuilderImpl(path);
    }
}