package org.neo4j.extension.querykiller.filter;

import org.codehaus.jackson.map.ObjectMapper;
import org.neo4j.extension.querykiller.QueryRegistryEntry;
import org.neo4j.extension.querykiller.QueryRegistryExtension;
import org.neo4j.extension.querykiller.http.CopyHttpServletRequest;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import java.io.IOException;

/**
 * QueryKillerFilter registers a cypher statement with a {@QueryRegistryExtension}
 * N.B.: a {@link CopyHttpServletRequest} is used for processing the filterChain
 * base class for filtering requests dealing with cypher statements.
 * Parsing the cypher query from the request is delegated to a derived class.
 */
public abstract class QueryKillerFilter implements Filter {

    protected QueryRegistryExtension queryRegistryExtension;

    private ObjectMapper objectMapper;

    public QueryKillerFilter(QueryRegistryExtension queryRegistryExtension) {
        this.queryRegistryExtension = queryRegistryExtension;
    }

    public ObjectMapper getObjectMapper() {
        return objectMapper;
    }

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        objectMapper = new ObjectMapper();
    }

    @Override
    public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException {

        HttpServletRequest copyRequest = new CopyHttpServletRequest((HttpServletRequest)request);

        String cypher = extractCypherFromRequest( copyRequest );
        QueryRegistryEntry queryMapEntry = queryRegistryExtension.registerQuery(
                cypher,
                copyRequest.getPathInfo(),
                copyRequest.getRemoteHost(),
                copyRequest.getRemoteUser() );
        try {
            chain.doFilter(copyRequest, response);
        } finally {
            queryRegistryExtension.unregisterQuery(queryMapEntry);
        }
    }

    protected abstract String extractCypherFromRequest(HttpServletRequest copyRequest) throws IOException;

    @Override
    public void destroy() {
        // intentionally empty
    }
}

@@ -277,16 +277,73 @@
 Request;
+%0Aimport org.slf4j.Logger;%0Aimport org.slf4j.LoggerFactory;
 %0A%0Aimport
@@ -811,24 +811,105 @@
 s Filter %7B%0A%0A
+    public final Logger log = LoggerFactory.getLogger(QueryKillerFilter.class);%0A%0A
     protecte
@@ -1507,24 +1507,128 @@
 xception %7B%0A%0A
+        if (shouldInterceptThisRequest(request)) %7B%0A%0A            log.debug( %22intercepting request%22);%0A    
         Http
@@ -1722,16 +1722,20 @@
         
+    
 String c
@@ -1791,16 +1791,20 @@
         
+   
+ 
 QueryReg
@@ -1888,16 +1888,20 @@
     
+    
 cypher,%0A
     
@@ -1896,16 +1896,20 @@
 cypher,%0A
+    
         
@@ -1951,32 +1951,36 @@
                 
+  
+  
 copyRequest.getR
@@ -1988,24 +1988,28 @@
 moteHost(),%0A
+    
             
@@ -2051,16 +2051,20 @@
         
+    
 try %7B%0A  
@@ -2073,16 +2073,20 @@
         
+ 
+   
 chain.do
@@ -2124,16 +2124,20 @@
         
+    
 %7D finall
@@ -2136,24 +2136,28 @@
 %7D finally %7B%0A
+    
             
@@ -2219,17 +2219,581 @@
         
-%7D
+        log.debug( %22intercepting request DONE%22);%0A            %7D%0A        %7D else %7B%0A            chain.doFilter(request, response);%0A        %7D%0A%0A    %7D%0A%0A    private boolean shouldInterceptThisRequest(ServletRequest request) %7B%0A        return true;%0A/*%0A        HttpServletRequest hsr = (HttpServletRequest) request;%0A        String origin = hsr.getHeader(%22Origin%22);%0A        String referer = hsr.getHeader(%22Referer%22);%0A        if ((origin==null) %7C%7C (referer==null)) %7B%0A            return false;%0A        %7D else %7B%0A            return referer.equals(origin+ %22/browser/%22);%0A        %7D%0A*/
 %0A    %7D%0A%0A

enable subclasses to skip request interception