/*
 * 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.meecrowave.gradle;

import org.apache.meecrowave.gradle.classloader.FilterGradleClassLoader;
import org.gradle.api.DefaultTask;
import org.gradle.api.GradleException;
import org.gradle.api.Project;
import org.gradle.api.artifacts.Configuration;
import org.gradle.api.tasks.Input;
import org.gradle.api.tasks.Optional;
import org.gradle.api.tasks.TaskAction;

import java.io.File;
import java.lang.reflect.Field;
import java.lang.reflect.InvocationTargetException;
import java.net.MalformedURLException;
import java.net.URL;
import java.net.URLClassLoader;
import java.util.Collection;
import java.util.HashSet;
import java.util.LinkedHashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import java.util.Scanner;
import java.util.concurrent.atomic.AtomicBoolean;
import java.util.stream.Stream;

import static java.util.Arrays.asList;
import static java.util.Optional.ofNullable;
import static java.util.stream.Collectors.toList;

// Note we can nest inputs objects, if you think it is better (jsonb, jsonp, jaxrs etc..) send a mail on the list ;)
public class MeecrowaveTask extends DefaultTask {
    private Configuration classpath;

    @Input
    @Optional
    private int watcherBouncing;

    @Input
    @Optional
    private int httpPort = 8080;

    @Input
    @Optional
    private int httpsPort = 8443;

    @Input
    @Optional
    private int stopPort = -1;

    @Input
    @Optional
    private String host = "localhost";

    @Input
    @Optional
    private String dir;

    @Input
    @Optional
    private String sharedLibraries;

    @Input
    @Optional
    private File serverXml;

    @Input
    @Optional
    private boolean keepServerXmlAsThis;

    @Input
    @Optional
    private boolean tomcatWrapLoader = false;

    @Input
    @Optional
    private Map<String, String> properties;

    @Input
    @Optional
    private boolean quickSession = true;

    @Input
    @Optional
    private boolean jaxrsLogProviders = false;

    @Input
    @Optional
    private boolean useTomcatDefaults = true;

    @Input
    @Optional
    private boolean skipHttp;

    @Input
    @Optional
    private boolean tomcatNoJmx = true;

    @Input
    @Optional
    private boolean injectServletContainerInitializer = true;

    @Input
    @Optional
    private boolean ssl;

    @Input
    @Optional
    private String keystoreFile;

    @Input
    @Optional
    private String keystorePass;

    @Input
    @Optional
    private String keystoreType;

    @Input
    @Optional
    private String clientAuth;

    @Input
    @Optional
    private String keyAlias;

    @Input
    @Optional
    private String sslProtocol;

    @Input
    @Optional
    private String webXml;

    @Input
    @Optional
    private String tomcatFilter;

    @Input
    @Optional
    private String loginConfig;

    @Input
    @Optional
    private Collection<String> securityConstraints = new LinkedList<>();

    @Input
    @Optional
    private Map<String, String> users;

    @Input
    @Optional
    private Map<String, String> roles;

    @Input
    @Optional
    private Map<String, String> cxfServletParams;

    @Input
    @Optional
    private boolean http2;

    @Input
    @Optional
    private String tempDir;

    @Input
    @Optional
    private boolean webResourceCached;

    @Input
    @Optional
    private boolean useLog4j2JulLogManager = System.getProperty("java.util.logging.manager") == null;

    @Input
    @Optional
    private String conf;

    @Input
    @Optional
    private boolean deleteBaseOnStartup = true;

    @Input
    @Optional
    private String jaxrsMapping = "/*";

    @Input
    @Optional
    private boolean jaxrsProviderSetup = true;

    @Input
    @Optional
    private String jaxrsDefaultProviders;

    @Input
    @Optional
    private boolean loggingGlobalSetup = true;

    @Input
    @Optional
    private boolean cdiConversation;

    @Input
    @Optional
    private boolean skip;

    @Input
    @Optional
    private boolean tomcatScanning = true;

    @Input
    @Optional
    private boolean tomcatAutoSetup = true;

    @Input
    @Optional
    private boolean useShutdownHook = true;

    @Input
    @Optional
    private List<File> modules;

    @Input
    @Optional
    private Collection<String> applicationScopes = new HashSet<>(asList("compile", "runtime"));

    @Input
    @Optional
    private Collection<String> classloaderFilteredPackages;

    @Input
    @Optional
    private String context = "";

    @Input
    @Optional
    private File webapp;

    @Input
    @Optional
    private String jsonpBufferStrategy = "QUEUE";

    @Input
    @Optional
    private int jsonpMaxStringLen = 10 * 1024 * 1024;

    @Input
    @Optional
    private int jsonpMaxReadBufferLen = 64 * 1024;

    @Input
    @Optional
    private int jsonpMaxWriteBufferLen = 64 * 1024;

    @Input
    @Optional
    private boolean jsonpSupportsComment = false;

    @Input
    @Optional
    private boolean jsonpPrettify = false;

    @Input
    @Optional
    private String jsonbEncoding = "UTF-8";

    @Input
    @Optional
    private boolean jsonbNulls = false;

    @Input
    @Optional
    private boolean jsonbIJson = false;

    @Input
    @Optional
    private boolean jsonbPrettify = false;

    @Input
    @Optional
    private String jsonbBinaryStrategy;

    @Input
    @Optional
    private String jsonbNamingStrategy;

    @Input
    @Optional
    private String jsonbOrderStrategy;

    @Input
    @Optional
    private String scanningIncludes;

    @Input
    @Optional
    private String scanningExcludes;

    @Input
    @Optional
    private String scanningPackageIncludes;

    @Input
    @Optional
    private String scanningPackageExcludes;

    @Input
    @Optional
    private String tomcatAccessLogPattern;

    @Input
    @Optional
    private boolean jaxrsAutoActivateBeanValidation = true;

    @Input
    @Optional
    private String meecrowaveProperties = "meecrowave.properties";

    @Input
    @Optional
    private boolean jaxwsSupportIfAvailable = true;

    @TaskAction
    public void bake() {
        fixConfig();

        final Thread thread = Thread.currentThread();
        final ClassLoader tccl = thread.getContextClassLoader();
        thread.setContextClassLoader(createLoader(tccl));
        try {
            doRun();
        } finally {
            thread.setContextClassLoader(tccl);
        }
    }

    private void doRun() {
        final Thread thread = Thread.currentThread();
        final ClassLoader loader = thread.getContextClassLoader();

        final AtomicBoolean running = new AtomicBoolean(false);
        Thread hook = null;
        AutoCloseable container;
        try {
            final Class<?> containerClass = loader.loadClass("org.apache.meecrowave.Meecrowave");
            final Class<?> configClass = loader.loadClass("org.apache.meecrowave.Meecrowave$Builder");

            final Object config = getConfig(configClass);

            running.set(true);
            container = AutoCloseable.class.cast(containerClass.getConstructor(configClass).newInstance(config));

            final AutoCloseable finalContainer = container;
            hook = new Thread() {
                @Override
                public void run() {
                    if (running.compareAndSet(true, false)) {
                        final Thread thread = Thread.currentThread();
                        final ClassLoader old = thread.getContextClassLoader();
                        thread.setContextClassLoader(loader);
                        try {
                            finalContainer.close();
                        } catch (final NoClassDefFoundError noClassDefFoundError) {
                            // debug cause it is too late to shutdown properly so don't pollute logs
                            getLogger().debug("can't stop Meecrowave", noClassDefFoundError);
                        } catch (final Exception e) {
                            getLogger().error("can't stop Meecrowave", e);
                        } finally {
                            thread.setContextClassLoader(old);
                        }
                    }
                }
            };
            hook.setName("Meecrowave-Embedded-ShutdownHook");
            Runtime.getRuntime().addShutdownHook(hook);

            containerClass.getMethod("start").invoke(container);
            final String fixedContext = ofNullable(context).orElse("");
            if (webapp == null) {
                containerClass.getMethod("deployClasspath", String.class).invoke(container, fixedContext);
            } else {
                containerClass.getMethod("deployWebapp", String.class, File.class).invoke(container, fixedContext, webapp);
            }

            getLogger().info("Meecrowave started on " + configClass.getMethod("getHost").invoke(config) + ":" + configClass.getMethod("getHttpPort").invoke(config));
        } catch (final Exception e) {
            ofNullable(hook).ifPresent(h -> {
                try {
                    h.run();
                } finally {
                    Runtime.getRuntime().removeShutdownHook(h);
                }
            });
            throw new GradleException(e.getMessage(), e);
        }

        try {
            String line;
            final Scanner scanner = new Scanner(System.in);
            while ((line = scanner.nextLine()) != null) {
                final String cmd = line.trim().toLowerCase(Locale.ENGLISH);
                switch (cmd) {
                    case "exit":
                    case "quit":
                        running.set(false);
                        try {
                            hook.run();
                        } finally {
                            Runtime.getRuntime().removeShutdownHook(hook);
                        }
                        return;
                    default:
                        getLogger().warn("Unknown: '" + cmd + "', use 'exit' or 'quit'");
                }
            }
        } catch (final Exception e) {
            Thread.interrupted();
        } finally {
            thread.setContextClassLoader(loader);
        }
    }

    private Object getConfig(final Class<?> configClass) throws Exception {
        final Object config = configClass.newInstance();
        for (final Field field : MeecrowaveTask.class.getDeclaredFields()) {
            try {
                final Field configField = configClass.getDeclaredField(field.getName());
                if (!configField.getType().equals(field.getType())) {
                    getLogger().debug("Skipping " + field.getName() + " since type doesnt match");
                    continue;
                }
                if (!field.isAccessible()) {
                    field.setAccessible(true);
                }

                final Object value = field.get(this);
                if (value != null) {
                    if (!configField.isAccessible()) {
                        configField.setAccessible(true);
                    }
                    configField.set(config, value);
                    getLogger().debug("using " + field.getName() + " = " + value);
                }
            } catch (final NoSuchFieldException nsfe) {
                // ignored
            } catch (final Exception e) {
                getLogger().warn("can't initialize attribute " + field.getName(), e);
            }
        }

        if (securityConstraints != null) {
            configClass.getMethod("setSecurityConstraints", Collection.class).invoke(config, securityConstraints.stream()
                    .map(item -> {
                        try {
                            final Class<?> recipeType = configClass.getClassLoader().loadClass("org.apache.xbean.recipe.ObjectRecipe");
                            final Class<?> builderType = configClass.getClassLoader().loadClass("org.apache.meecrowave.Meecrowave$SecurityConstaintBuilder");
                            final Object recipe = recipeType.getConstructor(Class.class).newInstance(builderType);
                            Stream.of(item.split(";"))
                                    .map(v -> v.split("="))
                                    .forEach(v -> {
                                        try {
                                            recipe.getClass().getMethod("setProperty", String.class, String.class).invoke(recipe, v[0], v[1]);
                                        } catch (final NoSuchMethodException | IllegalAccessException e) {
                                            throw new IllegalStateException(e);
                                        } catch (final InvocationTargetException e) {
                                            throw new IllegalStateException(e.getCause());
                                        }
                                    });
                            return recipe.getClass().getMethod("create", ClassLoader.class).invoke(recipe, configClass.getClassLoader());
                        } catch (final Exception cnfe) {
                            throw new IllegalArgumentException(item);
                        }
                    }).collect(toList()));
        }
        ofNullable(loginConfig).ifPresent(lc -> {
            try {
                final Class<?> recipeType = configClass.getClassLoader().loadClass("org.apache.xbean.recipe.ObjectRecipe");
                final Class<?> builderType = configClass.getClassLoader().loadClass("org.apache.meecrowave.Meecrowave$LoginConfigBuilder");
                final Object recipe = recipeType.getConstructor(Class.class).newInstance(builderType);
                Stream.of(loginConfig.split(";"))
                        .map(v -> v.split("="))
                        .forEach(v -> {
                            try {
                                recipe.getClass().getMethod("setProperty", String.class, String.class).invoke(recipe, v[0], v[1]);
                            } catch (final NoSuchMethodException | IllegalAccessException e) {
                                throw new IllegalStateException(e);
                            } catch (final InvocationTargetException e) {
                                throw new IllegalStateException(e.getCause());
                            }
                        });
                configClass.getMethod("setLoginConfig", Collection.class)
                        .invoke(config, recipe.getClass().getMethod("create", ClassLoader.class).invoke(recipe, configClass.getClassLoader()));
            } catch (final Exception cnfe) {
                throw new IllegalArgumentException(loginConfig);
            }
        });

        return config;
    }

    private ClassLoader createLoader(final ClassLoader parent) {
        final Collection<URL> urls = new LinkedHashSet<>(64);

        addFiles(modules, urls);

        for (final Configuration cc : getProject().getConfigurations()) {
            if (applicationScopes.contains(cc.getName())) {
                addFiles(cc.getFiles(), urls);
            }
        }

        addFiles(classpath.getFiles(), urls);

        // use JVM loader to avoid the noise of gradle and its plugins
        return new URLClassLoader(urls.toArray(new URL[urls.size()]), new FilterGradleClassLoader(parent, classloaderFilteredPackages));
    }

    private void addFiles(final Collection<File> files, final Collection<URL> urls) {
        if (files == null || files.isEmpty()) {
            return;
        }
        for (final File f : files) {
            final String name = f.getName();
            if (name.startsWith("slf4j-api") || name.startsWith("slf4j-jdk14")) {
                continue; // use gradle
            }
            try {
                urls.add(f.toURI().toURL());
            } catch (final MalformedURLException e) {
                throw new IllegalArgumentException(e);
            }
        }
    }

    private void fixConfig() {
        final Project project = getProject();

        // defaults
        if (classpath == null) {
            classpath = project.getConfigurations().getByName(MeecrowavePlugin.NAME);
        }

        if (dir == null) {
            dir = new File(project.getBuildDir(), "meecrowave/run").getAbsolutePath();
        }

        // extension override
        final MeecrowaveExtension extension = MeecrowaveExtension.class.cast(project.getExtensions().findByName(MeecrowavePlugin.NAME));
        if (extension != null) {
            for (final Field f : MeecrowaveTask.class.getDeclaredFields()) {
                if (f.isAnnotationPresent(Input.class)) {
                    try {
                        final Field extField = MeecrowaveExtension.class.getDeclaredField(f.getName());
                        if (!extField.isAccessible()) {
                            extField.setAccessible(true);
                        }
                        final Object val = extField.get(extension);
                        if (val != null) {
                            if (!f.isAccessible()) {
                                f.setAccessible(true);
                            }
                            f.set(this, val);
                        }
                    } catch (final IllegalAccessException | NoSuchFieldException e) {
                        getLogger().debug("No field " + f.getName() + " in " + extension, e);
                    }
                }
            }
        }
    }

    public Configuration getClasspath() {
        return classpath;
    }

    public void setClasspath(final Configuration classpath) {
        this.classpath = classpath;
    }

    public int getHttpPort() {
        return httpPort;
    }

    public void setHttpPort(final int httpPort) {
        this.httpPort = httpPort;
    }

    public int getHttpsPort() {
        return httpsPort;
    }

    public void setHttpsPort(final int httpsPort) {
        this.httpsPort = httpsPort;
    }

    public int getStopPort() {
        return stopPort;
    }

    public void setStopPort(final int stopPort) {
        this.stopPort = stopPort;
    }

    public String getHost() {
        return host;
    }

    public void setHost(final String host) {
        this.host = host;
    }

    public String getDir() {
        return dir;
    }

    public void setDir(final String dir) {
        this.dir = dir;
    }

    public File getServerXml() {
        return serverXml;
    }

    public void setServerXml(final File serverXml) {
        this.serverXml = serverXml;
    }

    public boolean isKeepServerXmlAsThis() {
        return keepServerXmlAsThis;
    }

    public void setKeepServerXmlAsThis(final boolean keepServerXmlAsThis) {
        this.keepServerXmlAsThis = keepServerXmlAsThis;
    }

    public Map<String, String> getProperties() {
        return properties;
    }

    public void setProperties(final Map<String, String> properties) {
        this.properties = properties;
    }

    public boolean isQuickSession() {
        return quickSession;
    }

    public void setQuickSession(final boolean quickSession) {
        this.quickSession = quickSession;
    }

    public boolean isSkipHttp() {
        return skipHttp;
    }

    public void setSkipHttp(final boolean skipHttp) {
        this.skipHttp = skipHttp;
    }

    public boolean isSsl() {
        return ssl;
    }

    public void setSsl(final boolean ssl) {
        this.ssl = ssl;
    }

    public String getKeystoreFile() {
        return keystoreFile;
    }

    public void setKeystoreFile(final String keystoreFile) {
        this.keystoreFile = keystoreFile;
    }

    public String getKeystorePass() {
        return keystorePass;
    }

    public void setKeystorePass(final String keystorePass) {
        this.keystorePass = keystorePass;
    }

    public String getKeystoreType() {
        return keystoreType;
    }

    public void setKeystoreType(final String keystoreType) {
        this.keystoreType = keystoreType;
    }

    public String getClientAuth() {
        return clientAuth;
    }

    public void setClientAuth(final String clientAuth) {
        this.clientAuth = clientAuth;
    }

    public String getKeyAlias() {
        return keyAlias;
    }

    public void setKeyAlias(final String keyAlias) {
        this.keyAlias = keyAlias;
    }

    public String getSslProtocol() {
        return sslProtocol;
    }

    public void setSslProtocol(final String sslProtocol) {
        this.sslProtocol = sslProtocol;
    }

    public String getWebXml() {
        return webXml;
    }

    public void setWebXml(final String webXml) {
        this.webXml = webXml;
    }

    public String getLoginConfig() {
        return loginConfig;
    }

    public void setLoginConfig(final String loginConfig) {
        this.loginConfig = loginConfig;
    }

    public Collection<String> getSecurityConstraints() {
        return securityConstraints;
    }

    public void setSecurityConstraints(final Collection<String> securityConstraints) {
        this.securityConstraints = securityConstraints;
    }

    public Map<String, String> getUsers() {
        return users;
    }

    public void setUsers(final Map<String, String> users) {
        this.users = users;
    }

    public Map<String, String> getRoles() {
        return roles;
    }

    public void setRoles(final Map<String, String> roles) {
        this.roles = roles;
    }

    public Map<String, String> getCxfServletParams() {
        return cxfServletParams;
    }

    public void setCxfServletParams(final Map<String, String> cxfServletParams) {
        this.cxfServletParams = cxfServletParams;
    }

    public boolean isHttp2() {
        return http2;
    }

    public void setHttp2(final boolean http2) {
        this.http2 = http2;
    }

    public String getTempDir() {
        return tempDir;
    }

    public void setTempDir(final String tempDir) {
        this.tempDir = tempDir;
    }

    public boolean isWebResourceCached() {
        return webResourceCached;
    }

    public void setWebResourceCached(final boolean webResourceCached) {
        this.webResourceCached = webResourceCached;
    }

    public String getConf() {
        return conf;
    }

    public void setConf(final String conf) {
        this.conf = conf;
    }

    public boolean isDeleteBaseOnStartup() {
        return deleteBaseOnStartup;
    }

    public void setDeleteBaseOnStartup(final boolean deleteBaseOnStartup) {
        this.deleteBaseOnStartup = deleteBaseOnStartup;
    }

    public String getJaxrsMapping() {
        return jaxrsMapping;
    }

    public void setJaxrsMapping(final String jaxrsMapping) {
        this.jaxrsMapping = jaxrsMapping;
    }

    public boolean isJaxrsProviderSetup() {
        return jaxrsProviderSetup;
    }

    public void setJaxrsProviderSetup(final boolean jaxrsProviderSetup) {
        this.jaxrsProviderSetup = jaxrsProviderSetup;
    }

    public boolean isLoggingGlobalSetup() {
        return loggingGlobalSetup;
    }

    public void setLoggingGlobalSetup(final boolean loggingGlobalSetup) {
        this.loggingGlobalSetup = loggingGlobalSetup;
    }

    public boolean isCdiConversation() {
        return cdiConversation;
    }

    public void setCdiConversation(final boolean cdiConversation) {
        this.cdiConversation = cdiConversation;
    }

    public boolean isSkip() {
        return skip;
    }

    public void setSkip(final boolean skip) {
        this.skip = skip;
    }

    public boolean isTomcatScanning() {
        return tomcatScanning;
    }

    public void setTomcatScanning(final boolean tomcatScanning) {
        this.tomcatScanning = tomcatScanning;
    }

    public List<File> getModules() {
        return modules;
    }

    public void setModules(final List<File> modules) {
        this.modules = modules;
    }

    public Collection<String> getApplicationScopes() {
        return applicationScopes;
    }

    public void setApplicationScopes(final Collection<String> applicationScopes) {
        this.applicationScopes = applicationScopes;
    }

    public Collection<String> getClassloaderFilteredPackages() {
        return classloaderFilteredPackages;
    }

    public void setClassloaderFilteredPackages(final Collection<String> classloaderFilteredPackages) {
        this.classloaderFilteredPackages = classloaderFilteredPackages;
    }

    public String getContext() {
        return context;
    }

    public void setContext(final String context) {
        this.context = context;
    }

    public File getWebapp() {
        return webapp;
    }

    public void setWebapp(final File webapp) {
        this.webapp = webapp;
    }

    public boolean isTomcatAutoSetup() {
        return tomcatAutoSetup;
    }

    public void setTomcatAutoSetup(final boolean tomcatAutoSetup) {
        this.tomcatAutoSetup = tomcatAutoSetup;
    }

    public boolean isUseShutdownHook() {
        return useShutdownHook;
    }

    public void setUseShutdownHook(final boolean useShutdownHook) {
        this.useShutdownHook = useShutdownHook;
    }

    public String getTomcatFilter() {
        return tomcatFilter;
    }

    public void setTomcatFilter(final String tomcatFilter) {
        this.tomcatFilter = tomcatFilter;
    }

    public boolean isUseTomcatDefaults() {
        return useTomcatDefaults;
    }

    public void setUseTomcatDefaults(final boolean useTomcatDefaults) {
        this.useTomcatDefaults = useTomcatDefaults;
    }

    public boolean isJaxrsLogProviders() {
        return jaxrsLogProviders;
    }

    public void setJaxrsLogProviders(final boolean jaxrsLogProviders) {
        this.jaxrsLogProviders = jaxrsLogProviders;
    }

    public boolean isTomcatWrapLoader() {
        return tomcatWrapLoader;
    }

    public void setTomcatWrapLoader(final boolean tomcatWrapLoader) {
        this.tomcatWrapLoader = tomcatWrapLoader;
    }

    public String getJaxrsDefaultProviders() {
        return jaxrsDefaultProviders;
    }

    public void setJaxrsDefaultProviders(final String jaxrsDefaultProviders) {
        this.jaxrsDefaultProviders = jaxrsDefaultProviders;
    }

    public String getSharedLibraries() {
        return sharedLibraries;
    }

    public void setSharedLibraries(final String sharedLibraries) {
        this.sharedLibraries = sharedLibraries;
    }

    public boolean isUseLog4j2JulLogManager() {
        return useLog4j2JulLogManager;
    }

    public void setUseLog4j2JulLogManager(final boolean useLog4j2JulLogManager) {
        this.useLog4j2JulLogManager = useLog4j2JulLogManager;
    }

    public String getScanningIncludes() {
        return scanningIncludes;
    }

    public void setScanningIncludes(final String scanningIncludes) {
        this.scanningIncludes = scanningIncludes;
    }

    public String getScanningExcludes() {
        return scanningExcludes;
    }

    public void setScanningExcludes(final String scanningExcludes) {
        this.scanningExcludes = scanningExcludes;
    }

    public String getJsonpBufferStrategy() {
        return jsonpBufferStrategy;
    }

    public void setJsonpBufferStrategy(final String jsonpBufferStrategy) {
        this.jsonpBufferStrategy = jsonpBufferStrategy;
    }

    public int getJsonpMaxStringLen() {
        return jsonpMaxStringLen;
    }

    public void setJsonpMaxStringLen(final int jsonpMaxStringLen) {
        this.jsonpMaxStringLen = jsonpMaxStringLen;
    }

    public int getJsonpMaxReadBufferLen() {
        return jsonpMaxReadBufferLen;
    }

    public void setJsonpMaxReadBufferLen(final int jsonpMaxReadBufferLen) {
        this.jsonpMaxReadBufferLen = jsonpMaxReadBufferLen;
    }

    public int getJsonpMaxWriteBufferLen() {
        return jsonpMaxWriteBufferLen;
    }

    public void setJsonpMaxWriteBufferLen(final int jsonpMaxWriteBufferLen) {
        this.jsonpMaxWriteBufferLen = jsonpMaxWriteBufferLen;
    }

    public boolean isJsonpSupportsComment() {
        return jsonpSupportsComment;
    }

    public void setJsonpSupportsComment(final boolean jsonpSupportsComment) {
        this.jsonpSupportsComment = jsonpSupportsComment;
    }

    public boolean isJsonpPrettify() {
        return jsonpPrettify;
    }

    public void setJsonpPrettify(final boolean jsonpPrettify) {
        this.jsonpPrettify = jsonpPrettify;
    }

    public String getJsonbEncoding() {
        return jsonbEncoding;
    }

    public void setJsonbEncoding(final String jsonbEncoding) {
        this.jsonbEncoding = jsonbEncoding;
    }

    public boolean isJsonbNulls() {
        return jsonbNulls;
    }

    public void setJsonbNulls(final boolean jsonbNulls) {
        this.jsonbNulls = jsonbNulls;
    }

    public boolean isJsonbIJson() {
        return jsonbIJson;
    }

    public void setJsonbIJson(final boolean jsonbIJson) {
        this.jsonbIJson = jsonbIJson;
    }

    public boolean isJsonbPrettify() {
        return jsonbPrettify;
    }

    public void setJsonbPrettify(final boolean jsonbPrettify) {
        this.jsonbPrettify = jsonbPrettify;
    }

    public String getJsonbBinaryStrategy() {
        return jsonbBinaryStrategy;
    }

    public void setJsonbBinaryStrategy(final String jsonbBinaryStrategy) {
        this.jsonbBinaryStrategy = jsonbBinaryStrategy;
    }

    public String getJsonbNamingStrategy() {
        return jsonbNamingStrategy;
    }

    public void setJsonbNamingStrategy(final String jsonbNamingStrategy) {
        this.jsonbNamingStrategy = jsonbNamingStrategy;
    }

    public String getJsonbOrderStrategy() {
        return jsonbOrderStrategy;
    }

    public void setJsonbOrderStrategy(final String jsonbOrderStrategy) {
        this.jsonbOrderStrategy = jsonbOrderStrategy;
    }

    public String getScanningPackageIncludes() {
        return scanningPackageIncludes;
    }

    public void setScanningPackageIncludes(final String scanningPackageIncludes) {
        this.scanningPackageIncludes = scanningPackageIncludes;
    }

    public String getScanningPackageExcludes() {
        return scanningPackageExcludes;
    }

    public void setScanningPackageExcludes(final String scanningPackageExcludes) {
        this.scanningPackageExcludes = scanningPackageExcludes;
    }

    public boolean isTomcatNoJmx() {
        return tomcatNoJmx;
    }

    public void setTomcatNoJmx(final boolean tomcatNoJmx) {
        this.tomcatNoJmx = tomcatNoJmx;
    }

    public boolean isInjectServletContainerInitializer() {
        return injectServletContainerInitializer;
    }

    public void setInjectServletContainerInitializer(final boolean injectServletContainerInitializer) {
        this.injectServletContainerInitializer = injectServletContainerInitializer;
    }

    public String getTomcatAccessLogPattern() {
        return tomcatAccessLogPattern;
    }

    public void setTomcatAccessLogPattern(final String tomcatAccessLogPattern) {
        this.tomcatAccessLogPattern = tomcatAccessLogPattern;
    }

    public boolean isJaxrsAutoActivateBeanValidation() {
        return jaxrsAutoActivateBeanValidation;
    }

    public void setJaxrsAutoActivateBeanValidation(final boolean jaxrsAutoActivateBeanValidation) {
        this.jaxrsAutoActivateBeanValidation = jaxrsAutoActivateBeanValidation;
    }

    public String getMeecrowaveProperties() {
        return meecrowaveProperties;
    }

    public void setMeecrowaveProperties(final String meecrowaveProperties) {
        this.meecrowaveProperties = meecrowaveProperties;
    }

    public int getWatcherBouncing() {
        return watcherBouncing;
    }

    public void setWatcherBouncing(final int watcherBouncing) {
        this.watcherBouncing = watcherBouncing;
    }

    public boolean isJaxwsSupportIfAvailable() {
        return jaxwsSupportIfAvailable;
    }

    public void setJaxwsSupportIfAvailable(final boolean jaxwsSupportIfAvailable) {
        this.jaxwsSupportIfAvailable = jaxwsSupportIfAvailable;
    }
}
