// Path: core/src/main/java/org/nesty/core/server/NestyOptionProvider.java
// public class NestyOptionProvider {
// 
//     private Map<NestyOptions<?>, Object> options = new ConcurrentHashMap<>();
// 
//     public <T> NestyOptionProvider option(NestyOptions<T> option, T value) {
//         this.options.put(option, value);
//         return this;
//     }
// 
//     /**
//      * return specified option name's value if this option is setted. or named option
//      * default value.
//      *
//      * @param option named option already defined
//      * @return setted value or default value
//      */
//     @SuppressWarnings("unchecked")
//     public <T> T option(NestyOptions<T> option) {
//         T value;
//         if ((value = (T) options.get(option)) != null)
//             return value;
//         else
//             return option.defaultValue();
//     }
// }
// 
// Path: core/src/main/java/org/nesty/core/server/rest/HttpContext.java
// public class HttpContext extends HttpSession {
//     private static String NestyUID = UUID.randomUUID().toString();
//     private static AtomicLong SequenceId = new AtomicLong(0);
// 
//     // raw body
//     protected String httpBody;
//     // params include query string and body param
//     protected Map<String, String> httpParams;
//     // attribute map values
//     protected Map<String, Object> httpAttributes;
//     // header values
//     protected Map<String, String> httpHeaders;
//     // client request with unique id, fetch it from http header(Request-Id)
//     // if exsit. or generate by UUID
//     private String requestId = String.format("%s-%d", NestyUID, SequenceId.incrementAndGet());
//     // ip address from origin client, fetch it from getRemoteAddr()
//     // or header X-FORWARDED-FOR
//     private String remoteAddress;
//     //  raw uri exclude query string
//     private String uri;
//     // http uri terms split by "/"
//     private String[] terms;
//     // Http request method. NOT null
//     private RequestMethod requestMethod;
//     // Http long connection
//     private boolean isKeepAlive = true;
// 
//     private HttpContext() {
//     }
// 
//     public static HttpContext build(HttpRequestVisitor visitor) {
//         HttpContext context = new HttpContext();
//         context.remoteAddress = visitor.visitRemoteAddress();
//         context.uri = visitor.visitURI();
//         context.terms = visitor.visitTerms();
//         context.requestMethod = visitor.visitHttpMethod();
//         context.httpHeaders = visitor.visitHttpHeaders();
//         context.httpParams = visitor.visitHttpParams();
// 
//         // TODO : if exclude GET or not ?
//         //
//         context.httpBody = visitor.visitHttpBody();
// 
//         if (visitor.visitHttpVersion() == HttpVersion.HTTP_1_1 &&
//                 HttpConstants.HEADER_CONNECTION_CLOSE.equals(context.httpHeaders.get(HttpConstants.HEADER_CONNECTION)))
//             context.isKeepAlive = false;
// 
//         if (visitor.visitHttpVersion() == HttpVersion.HTTP_1_0 &&
//                 !HttpConstants.HEADER_CONNECTION_KEEPALIVE.equalsIgnoreCase(context.httpHeaders.get(HttpConstants.HEADER_CONNECTION)))
//             context.isKeepAlive = false;
// 
//         return context;
//     }
// 
//     public boolean isKeepAlive() {
//         return isKeepAlive;
//     }
// 
//     public String getRemoteAddress() {
//         return remoteAddress;
//     }
// 
//     public String getUri() {
//         return uri;
//     }
// 
//     public String[] getTerms() {
//         return terms;
//     }
// 
//     public RequestMethod getRequestMethod() {
//         return requestMethod;
//     }
// 
//     public String getHttpBody() {
//         return httpBody;
//     }
// 
//     @Override
//     public Map<String, String> getHttpParams() {
//         return httpParams;
//     }
// 
//     public Map<String, String> getHttpHeaders() {
//         return httpHeaders;
//     }
// 
//     @Override
//     public String getRequestId() {
//         return requestId;
//     }
// 
//     @Override
//     public Map<String, Object> getHttpAttributes() {
//         return httpAttributes;
//     }
// }


import io.netty.handler.codec.http.DefaultFullHttpResponse;
import org.nesty.core.server.NestyOptionProvider;
import org.nesty.core.server.rest.HttpContext;
package org.nesty.core.server.rest.interceptor;


/**
 * Filter of http request and response
 *
 * Author : Michael
 * Date : March 09, 2016
 */
public abstract class Interceptor {

    public boolean install(NestyOptionProvider nesty) {
        return true;
    }

    public void destroy() {
    }

    /**
     * http context of request information. user can update
     * the value of context.
     *
     * @param context http context
     * @return true if we continue the request or false will deny the request by http code 403
     */
// Path: core/src/main/java/org/nesty/core/server/NestyOptionProvider.java
// public class NestyOptionProvider {
// 
//     private Map<NestyOptions<?>, Object> options = new ConcurrentHashMap<>();
// 
//     public <T> NestyOptionProvider option(NestyOptions<T> option, T value) {
//         this.options.put(option, value);
//         return this;
//     }
// 
//     /**
//      * return specified option name's value if this option is setted. or named option
//      * default value.
//      *
//      * @param option named option already defined
//      * @return setted value or default value
//      */
//     @SuppressWarnings("unchecked")
//     public <T> T option(NestyOptions<T> option) {
//         T value;
//         if ((value = (T) options.get(option)) != null)
//             return value;
//         else
//             return option.defaultValue();
//     }
// }
// 
// Path: core/src/main/java/org/nesty/core/server/rest/HttpContext.java
// public class HttpContext extends HttpSession {
//     private static String NestyUID = UUID.randomUUID().toString();
//     private static AtomicLong SequenceId = new AtomicLong(0);
// 
//     // raw body
//     protected String httpBody;
//     // params include query string and body param
//     protected Map<String, String> httpParams;
//     // attribute map values
//     protected Map<String, Object> httpAttributes;
//     // header values
//     protected Map<String, String> httpHeaders;
//     // client request with unique id, fetch it from http header(Request-Id)
//     // if exsit. or generate by UUID
//     private String requestId = String.format("%s-%d", NestyUID, SequenceId.incrementAndGet());
//     // ip address from origin client, fetch it from getRemoteAddr()
//     // or header X-FORWARDED-FOR
//     private String remoteAddress;
//     //  raw uri exclude query string
//     private String uri;
//     // http uri terms split by "/"
//     private String[] terms;
//     // Http request method. NOT null
//     private RequestMethod requestMethod;
//     // Http long connection
//     private boolean isKeepAlive = true;
// 
//     private HttpContext() {
//     }
// 
//     public static HttpContext build(HttpRequestVisitor visitor) {
//         HttpContext context = new HttpContext();
//         context.remoteAddress = visitor.visitRemoteAddress();
//         context.uri = visitor.visitURI();
//         context.terms = visitor.visitTerms();
//         context.requestMethod = visitor.visitHttpMethod();
//         context.httpHeaders = visitor.visitHttpHeaders();
//         context.httpParams = visitor.visitHttpParams();
// 
//         // TODO : if exclude GET or not ?
//         //
//         context.httpBody = visitor.visitHttpBody();
// 
//         if (visitor.visitHttpVersion() == HttpVersion.HTTP_1_1 &&
//                 HttpConstants.HEADER_CONNECTION_CLOSE.equals(context.httpHeaders.get(HttpConstants.HEADER_CONNECTION)))
//             context.isKeepAlive = false;
// 
//         if (visitor.visitHttpVersion() == HttpVersion.HTTP_1_0 &&
//                 !HttpConstants.HEADER_CONNECTION_KEEPALIVE.equalsIgnoreCase(context.httpHeaders.get(HttpConstants.HEADER_CONNECTION)))
//             context.isKeepAlive = false;
// 
//         return context;
//     }
// 
//     public boolean isKeepAlive() {
//         return isKeepAlive;
//     }
// 
//     public String getRemoteAddress() {
//         return remoteAddress;
//     }
// 
//     public String getUri() {
//         return uri;
//     }
// 
//     public String[] getTerms() {
//         return terms;
//     }
// 
//     public RequestMethod getRequestMethod() {
//         return requestMethod;
//     }
// 
//     public String getHttpBody() {
//         return httpBody;
//     }
// 
//     @Override
//     public Map<String, String> getHttpParams() {
//         return httpParams;
//     }
// 
//     public Map<String, String> getHttpHeaders() {
//         return httpHeaders;
//     }
// 
//     @Override
//     public String getRequestId() {
//         return requestId;
//     }
// 
//     @Override
//     public Map<String, Object> getHttpAttributes() {
//         return httpAttributes;
//     }
// }


// Path: core/src/main/java/org/nesty/core/server/rest/interceptor/Interceptor.java
import io.netty.handler.codec.http.DefaultFullHttpResponse;
import org.nesty.core.server.NestyOptionProvider;
import org.nesty.core.server.rest.HttpContext;

package org.nesty.core.server.rest.interceptor;


/**
 * Filter of http request and response
 *
 * Author : Michael
 * Date : March 09, 2016
 */
public abstract class Interceptor {

    public boolean install(NestyOptionProvider nesty) {
        return true;
    }

    public void destroy() {
    }

    /**
     * http context of request information. user can update
     * the value of context.
     *
     * @param context http context
     * @return true if we continue the request or false will deny the request by http code 403
     */
    public boolean filter(final HttpContext context) {