package com.itranswarp.jxrest;

import java.io.IOException;
import java.util.stream.Stream;

import javax.servlet.Filter;
import javax.servlet.FilterChain;
import javax.servlet.FilterConfig;
import javax.servlet.ServletException;
import javax.servlet.ServletRequest;
import javax.servlet.ServletResponse;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;

/**
 * A REST API filter to handle REST API calls.
 * 
 * @author Michael Liao
 */
public class RestApiFilter extends RestApiHandler implements Filter {

    final Log log = LogFactory.getLog(getClass());
    String urlPrefix = "";

    /**
     * Set URL prefix. e.g. "/api/v1".
     * 
     * @param prefix Prefix string, or null if no prefix.
     */
    public void setUrlPrefix(String prefix) {
        prefix = (prefix == null) ? "" : prefix.trim();
        if (prefix.endsWith("/")) {
            prefix = prefix.substring(0, prefix.length() - 1);
        }
        if (!prefix.isEmpty() && !prefix.startsWith("/")) {
            log.error("Invalid urlPrefix: must start with /, but actual is: " + prefix);
            throw new IllegalArgumentException("Invalid urlPrefix parameter: " + prefix);
        }
        log.info("Set urlPrefix of RestApiFilter to: " + prefix);
        this.urlPrefix = prefix;
    }

    public void init(FilterConfig config) throws ServletException {
        log.info("Init RestApiFilter...");
        setUrlPrefix(config.getInitParameter("urlPrefix"));
        String handlers = config.getInitParameter("handlers");
        if (handlers != null) {
            Stream.of(handlers.split("\\,")).map((s) -> {
                return s.trim();
            }).filter((s) -> {
                return !s.isEmpty();
            }).forEach((s) -> {
                findHandlers(s);
            });
        }
    }

    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {
        HttpServletRequest req = (HttpServletRequest) request;
        String path = req.getRequestURI();
        if (path.startsWith(this.urlPrefix)) {
            String apiUrl = path.substring(this.urlPrefix.length());
            if (apiUrl.startsWith("/")) {
                log.info("Process API request: " + apiUrl);
                processApi(req, (HttpServletResponse) response, req.getMethod(), apiUrl);
                return;
            }
        }
        chain.doFilter(request, response);
    }

    public void destroy() {
        log.info("Destroy RestApiFilter...");
    }

}

@@ -592,31 +592,8 @@
 ter 
-extends RestApiHandler 
 impl
@@ -608,16 +608,16 @@
 ilter %7B%0A
+
 %0A    fin
@@ -686,16 +686,270 @@
 ix = %22%22;
+%0A    RestApiHandler handler = null;%0A%0A    /**%0A     * Set RestApiHandler to handle REST API.%0A     * %0A     * @param handler Instance of RestApiHandler.%0A     */%0A    public void setRestApiHandler(RestApiHandler handler) %7B%0A        this.handler = handler;%0A    %7D
 %0A%0A    /*
@@ -1736,24 +1736,119 @@
 ilter...%22);%0A
+        if (this.handler != null) %7B%0A            this.handler = new RestApiHandler();%0A        %7D%0A
         setU
@@ -2197,16 +2197,29 @@
         
+this.handler.
 findHand
@@ -2456,16 +2456,83 @@
 equest;%0A
+        HttpServletResponse resp = (HttpServletResponse) response;%0A
         
@@ -2800,16 +2800,29 @@
         
+this.handler.
 processA
@@ -2833,38 +2833,12 @@
 eq, 
-(HttpServletResponse) response
+resp
 , re

refactor RestApiFilter