Package org.atmosphere.nettosphere

Source Code of org.atmosphere.nettosphere.Config$Builder

/*
* Copyright 2014 Jeanfrancois Arcand
*
* Licensed 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.atmosphere.nettosphere;

import java.io.File;
import java.io.IOException;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.concurrent.ExecutorService;

import javax.net.ssl.SSLContext;
import javax.servlet.Servlet;

import org.atmosphere.cpr.AtmosphereFramework;
import org.atmosphere.cpr.AtmosphereHandler;
import org.atmosphere.cpr.AtmosphereInterceptor;
import org.atmosphere.cpr.AtmosphereResource;
import org.atmosphere.cpr.Broadcaster;
import org.atmosphere.cpr.BroadcasterCache;
import org.atmosphere.cpr.BroadcasterFactory;
import org.atmosphere.handler.AbstractReflectorAtmosphereHandler;
import org.atmosphere.handler.ReflectorServletProcessor;
import org.atmosphere.nettosphere.util.SSLContextListener;
import org.atmosphere.websocket.WebSocketProtocol;
import org.atmosphere.websocket.protocol.SimpleHttpProtocol;
import org.jboss.netty.channel.ChannelUpstreamHandler;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

/**
* A Configuration class used to configure Atmosphere.
*/
public class Config {
    private static final Logger logger = LoggerFactory.getLogger(Config.class);
    private final Builder b;

    public Config(Builder b) {
        this.b = b;
    }

    public ExecutorService bossExecutor() {
      return b.bossExecutor;
    }
   
    public ExecutorService workerExecutor() {
      return b.workerExecutor;
    }
   
    public String host() {
        return b.host;
    }

    public int port() {
        return b.port;
    }

    public Map<String, String> initParams() {
        return b.initParams;
    }

    public List<String> path() {
        return b.paths;
    }

    public String configFile() {
        return b.atmosphereDotXmlPath;
    }

    public Class<? extends Broadcaster> broadcaster() {
        return b.broadcasterClass;
    }

    public Map<String, AtmosphereHandler> handlersMap() {
        return b.handlers;
    }

    public BroadcasterFactory broadcasterFactory() {
        return b.broadcasterFactory;
    }

    public Class<? extends BroadcasterCache> broadcasterCache() {
        return b.broadcasterCache;
    }

    public Class<? extends WebSocketProtocol> webSocketProtocol() {
        return b.webSocketProtocol;
    }

    public List<AtmosphereInterceptor> interceptors() {
        return b.interceptors;
    }

    public String scanLib() {
        return b.librariesPath;
    }

    public List<Class<?>> scanPackages() {
        return b.packages;
    }

    public String mappingPath() {
        return b.mappingPath;
    }

    public SSLContext sslContext() {
        return b.context;
    }

    public SSLContextListener sslContextListener() {
        return b.listener;
    }

    public LinkedList<ChannelUpstreamHandler> channelUpstreamHandlers() {
        return b.nettyHandlers;
    }

    public boolean supportChunking() {
        return b.supportChunking;
    }

    public boolean aggregateRequestBodyInMemory() {
        return b.aggregateRequestBodyInMemory;
    }

    public boolean socketKeepAlive() {
        return b.socketKeepAlive;
    }

    public boolean socketNoTcpDelay() {
        return b.socketNoTcpDelay;
    }

    public int maxChunkContentLength() {
        return b.maxContentLength;
    }

    public int  writeBufferPoolSize(){
        return b.writeBufferPoolSize;
    }

    public long writeBufferPoolCleanupFrequency(){
        return b.writeBufferPoolCleanupFrequency;
    }

    public List<String> excludedInterceptors(){
        return b.excludedInterceptors;
    }

    public boolean enablePong(){
        return b.enablePong;
    }

    public final static class Builder {
        private final List<String> paths = new ArrayList<String>();
        private String atmosphereDotXmlPath = AtmosphereFramework.DEFAULT_ATMOSPHERE_CONFIG_PATH;
        private ExecutorService bossExecutor;
        private ExecutorService workerExecutor;
        private String host = "0.0.0.0";
        private int port = 8080;
        private final Map<String, String> initParams = new HashMap<String, String>();
        private final Map<String, AtmosphereHandler> handlers = new HashMap<String, AtmosphereHandler>();
        private Class<? extends WebSocketProtocol> webSocketProtocol = SimpleHttpProtocol.class;

        private Class<? extends Broadcaster> broadcasterClass;
        private BroadcasterFactory broadcasterFactory;
        private Class<? extends BroadcasterCache> broadcasterCache;
        private final List<AtmosphereInterceptor> interceptors = new ArrayList<AtmosphereInterceptor>();
        private final List<String> excludedInterceptors = new ArrayList<String>();
        private String librariesPath = "." + File.separator + "lib";
        private String mappingPath = "";
        private final List<Class<?>> packages = new ArrayList<Class<?>>();
        private SSLContext context;
        private SSLContextListener listener = SSLContextListener.DEFAULT;
        private final LinkedList<ChannelUpstreamHandler> nettyHandlers = new LinkedList<ChannelUpstreamHandler>();
        private boolean supportChunking = true;
        private boolean aggregateRequestBodyInMemory = true;
        private boolean socketNoTcpDelay = true;
        private boolean socketKeepAlive = true;
        private int maxContentLength = 65536;
        private int writeBufferPoolSize = 50;
        private long writeBufferPoolCleanupFrequency = 30000;
        private boolean enablePong = false;

        /**
         * Set an SSLContext in order enable SSL
         *
         * @param context
         * @return this
         */
        public Builder sslContext(SSLContext context) {
            this.context = context;
            return this;
        }

        /**
         * Add a {@link SSLContextListener}
         *
         * @param listener
         * @return this
         */
        public Builder sslContextListener(SSLContextListener listener) {
            this.listener = listener;
            return this;
        }

        /**
         * Set the mapping path. If you have worked with Servlet, the mapping path is equivalent to the servlet path.
         *
         * @param mappingPath the path under which the application will be mapped.
         * @return this
         */
        public Builder mappingPath(String mappingPath) {
            this.mappingPath = mappingPath;
            return this;
        }

        /**
         * Enable WebSokcet Pong message. Disabled by default.
         *
         * @param enablePong Enable WebSokcet Pong message
         * @return this
         */
        public Builder enablePong(boolean enablePong) {
            this.enablePong = enablePong;
            return this;
        }

        /**
         * When {@link #aggregateRequestBodyInMemory} is true,the maximum length of the aggregated content.
         * If the length of the aggregated content exceeds this value,
         * a {@link org.jboss.netty.handler.codec.frame.TooLongFrameException} will be raised.
         *
         * @return this
         */
        public Builder maxChunkContentLength(int maxChunkContentLength) {
            this.maxContentLength = maxChunkContentLength;
            return this;
        }

        /**
         * Set the path to the library when annotation scanning is enabled. Default is "./". Use this method
         * when your annotated resource is packaged inside the jar/zip.
         *
         * @param librariesPath the path to the library when annotation scanning is enabled.
         * @return this
         */
        public Builder scanLibrary(String librariesPath) {
            this.librariesPath = librariesPath;
            return this;
        }

        /**
         * The path location of the atmosphere.xml file.
         *
         * @param atmosphereDotXmlPath path location of the atmosphere.xml file.
         * @return this
         */
        public Builder configFile(String atmosphereDotXmlPath) {
            this.atmosphereDotXmlPath = atmosphereDotXmlPath;
            return this;
        }
       
        /**
         * The Executor to be used in providing (the) I/O boss-thread(s).
         *
         * @param bossExecutor ExecutorService to be used for boss threads.
         * @return this
         */
        public Builder bossExecutor(ExecutorService bossExecutor) {
            this.bossExecutor = bossExecutor;
            return this;
        }
       
        /**
         * The Executor to be used in providing (the) I/O worker-thread(s).
         *
         * @param workerExecutor ExecutorService to be used for worker threads.
         * @return this
         */
        public Builder workerExecutor(ExecutorService workerExecutor) {
            this.workerExecutor = workerExecutor;
            return this;
        }
       
        /**
         * The server's host
         *
         * @param host server's host
         * @return this
         */
        public Builder host(String host) {
            this.host = host;
            return this;
        }

        /**
         * The server's port
         *
         * @param port server's port
         * @return this
         */
        public Builder port(int port) {
            this.port = port;
            return this;
        }

        /**
         * Add some init param
         *
         * @param name  the name
         * @param value the value
         * @return this
         */
        public Builder initParam(String name, String value) {
            initParams.put(name, value);
            return this;
        }

        /**
         * Add a path to scan when looking for static resources like javascript file, html, etc.
         *
         * @param path
         * @return this
         */
        public Builder resource(String path) {
            paths.add(path);
            return this;
        }

        /**
         * Add an {@link AtmosphereHandler} that will be mapped to the specified path
         *
         * @param path a mapping path
         * @param c    an {@link AtmosphereHandler}
         * @return this
         */
        public Builder resource(String path, AtmosphereHandler c) {
            handlers.put(path, c);
            return this;
        }

        /**
         * Add an {@link Servlet} that will be mapped to the specified path
         *
         * @param path a mapping path
         * @param c    an {@link Servlet}
         * @return this
         */
        public Builder resource(String path, Servlet c) {
            handlers.put(path, new ReflectorServletProcessor(c));
            return this;
        }

        /**
         * Add an {@link Handler} mapped to the default, which is '/*'
         *
         * @param handler {@link Handler}
         * @return this
         */
        public Builder resource(Handler handler) {
            return resource("/*", handler);
        }

        /**
         * Add an {@link Handler} that will be mapped to the specified path
         *
         * @param handler {@link Handler}
         * @return this
         */
        public Builder resource(String path, final Handler handler) {
            handlers.put(path, new AbstractReflectorAtmosphereHandler() {
                @Override
                public void onRequest(AtmosphereResource resource) throws IOException {
                    handler.handle(resource);
                }

                @Override
                public void destroy() {
                }
            });
            return this;
        }

        /**
         * Add an annotated class. The annotation can be from Atmosphere or Jersey.
         *
         * @param c an annotated class. The annotation can be from Atmosphere or Jersey.
         * @return this
         */
        public Builder resource(Class<?> c) {
            packages.add(c);
            return this;
        }

        /**
         * Add an {@link AtmosphereHandler} or {@link Servlet} class
         *
         * @param path a mapping path
         * @param c    an {@link AtmosphereHandler} or {@link Servlet} class
         * @return this
         */
        public Builder resource(String path, Class<?> c) {
            try {
                if (AtmosphereHandler.class.isAssignableFrom(c)) {
                    handlers.put(path, AtmosphereHandler.class.cast(c.newInstance()));
                } else if (Servlet.class.isAssignableFrom(c)) {
                    handlers.put(path, new ReflectorServletProcessor(Servlet.class.cast(c.newInstance())));
                } else {
                    throw new IllegalStateException("You class must implements AtmosphereHandler or be a Servlet");
                }
            } catch (Exception ex) {
                logger.error("Invalid resource {}", c);
            }
            return this;
        }

        /**
         * Configure the default {@link Broadcaster}
         *
         * @param broadcasterClass a Broadcaster
         * @return this
         */
        public Builder broadcaster(Class<? extends Broadcaster> broadcasterClass) {
            this.broadcasterClass = broadcasterClass;
            return this;
        }

        /**
         * Configure the default {@link BroadcasterFactory}
         *
         * @param broadcasterFactory a BroadcasterFactory's class
         * @return this
         */
        public Builder broadcasterFactory(BroadcasterFactory broadcasterFactory) {
            this.broadcasterFactory = broadcasterFactory;
            return this;
        }

        /**
         * Configure the default {@link BroadcasterCache}
         *
         * @param broadcasterCache a BroadcasterCache's class
         * @return this
         */
        public Builder broadcasterCache(Class<? extends BroadcasterCache> broadcasterCache) {
            this.broadcasterCache = broadcasterCache;
            return this;
        }

        /**
         * Configure the default {@link WebSocketProtocol}
         *
         * @param webSocketProtocol a WebSocketProtocol's class
         * @return this
         */
        public Builder webSocketProtocol(Class<? extends WebSocketProtocol> webSocketProtocol) {
            this.webSocketProtocol = webSocketProtocol;
            return this;
        }

        /**
         * Add an {@link AtmosphereInterceptor}
         *
         * @param interceptor an {@link AtmosphereInterceptor}
         * @return this
         */
        public Builder interceptor(AtmosphereInterceptor interceptor) {
            interceptors.add(interceptor);
            return this;
        }

        /**
         * Exclude an {@link AtmosphereInterceptor} from being added, at startup, by Atmosphere. The default's {@link AtmosphereInterceptor} 
         * are candidates for being excluded
         *
         * @param interceptor an {@link AtmosphereInterceptor}
         * @return this
         */
        public Builder excludeInterceptor(String interceptor) {
            excludedInterceptors.add(interceptor);
            return this;
        }

        /**
         * Add a {@link ChannelUpstreamHandler}. All will be executed before {@link BridgeRuntime}
         *
         * @param h {@link ChannelUpstreamHandler}
         * @return this;
         */
        public Builder channelUpstreamHandler(ChannelUpstreamHandler h) {
            nettyHandlers.addLast(h);
            return this;
        }

        /**
         * Set to false to override the default behavior when writing bytes, which is use chunking. When set to false
         * the {@link org.jboss.netty.handler.stream.ChunkedWriteHandler} will not be added to the Netty's {@link org.jboss.netty.channel.ChannelPipeline}
         * <p/>
         * This is strongly recommended to turn chunking to false if you are using websocket to get better performance.
         *
         * @param supportChunking false to disable.
         * @return this
         */
        public Builder supportChunking(boolean supportChunking) {
            this.supportChunking = supportChunking;
            return this;
        }

        /**
         * By default, Nettosphere aggregate the HTTP request's body in memory an invoke an Atmosphere's components with
         * a single {@link AtmosphereResource}. Setting supportChunkAggregator to false will instead invoke Atmosphere's component
         * with a new {@link AtmosphereResource} each time the request's body is read in memory. Setting to false
         * may significantly increase the performance and reduce memory footprint. Note that setting this value to false
         * may deliver to your Atmosphere's component partial body, so your application must make sure to aggregate the
         * body before parsing the data if needed. For example, if you are using JSON as format, make sure you parse the
         * data incrementally.
         *
         * @param aggregateRequestBodyInMemory false to disable.
         * @return this
         */
        public Builder aggregateRequestBodyInMemory(boolean aggregateRequestBodyInMemory) {
            this.aggregateRequestBodyInMemory = aggregateRequestBodyInMemory;
            return this;
        }

        /**
         * Set Netty's Bootstrap 'child.tcpDelay'
         *
         * @param socketNoTcpDelay
         * @return this
         */
        public Builder socketNoTcpDelay(boolean socketNoTcpDelay) {
            this.socketNoTcpDelay = socketNoTcpDelay;
            return this;
        }

        /**
         * Set Netty's Bootstrap 'child.keepAlive'
         *
         * @param socketKeepAlive
         * @return this
         */
        public Builder socketKeepAlive(boolean socketKeepAlive) {
            this.socketKeepAlive = socketKeepAlive;
            return this;
        }

        /**
         * The internal size of the underlying {@link org.atmosphere.nettosphere.util.ChannelBufferPool} size for
         * I/O operation. Default is 50. If set to -1, a new {@link org.jboss.netty.buffer.ChannelBuffer} will be
         * created and never pooled.
         *
         * @param writeBufferPoolSize the max size of the pool.
         * @return this;
         */
        public Builder writeBufferPoolSize(int writeBufferPoolSize){
            this.writeBufferPoolSize = writeBufferPoolSize;
            return this;
        }

        /**
         * The frequency the {@link org.atmosphere.nettosphere.util.ChannelBufferPool} is resized and garbaged. Default
         * is 30000.
         * @param writeBufferPoolCleanupFrequency  the frequency
         * @return this
         */
        public Builder writeBufferPoolCleanupFrequency(long writeBufferPoolCleanupFrequency) {
            this.writeBufferPoolCleanupFrequency = writeBufferPoolCleanupFrequency;
            return this;
        }

        /**
         * Build an instance of this class.
         *
         * @return
         */
        public Config build() {
            if (paths.isEmpty()) {
                paths.add("/");
            }
            return new Config(this);
        }
    }
}
TOP

Related Classes of org.atmosphere.nettosphere.Config$Builder

TOP
Copyright © 2018 www.massapi.com. All rights reserved.
All source code are property of their respective owners. Java is a trademark of Sun Microsystems, Inc and owned by ORACLE Inc. Contact coftware#gmail.com.