All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.britesnow.snow.web.rest.RestRegistry Maven / Gradle / Ivy

package com.britesnow.snow.web.rest;

import java.lang.reflect.Method;
import java.util.HashMap;
import java.util.Map;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import javax.inject.Singleton;

import com.britesnow.snow.util.Pair;
import com.britesnow.snow.web.RequestContext;
import com.britesnow.snow.web.HttpMethod;
import com.britesnow.snow.web.handler.ParamDef;

/**
 * Note: the registerWeb*** must be called only in init time, as the Map are not concurrent 
 * for performance reasons. 
 * 
 * Internal only. 
 * 
 * @author jeremychone
 * @since  2.0.0
 *
 */
@Singleton
public class RestRegistry {
    
    private Map webGetRefByPath = new HashMap();
    private Map webPostRefByPath = new HashMap();
    private Map webPutRefByPath = new HashMap();
    private Map webDeleteRefByPath = new HashMap();
    
    private Map webGetRefByVaredPath = new HashMap();
    private Map webPostRefByVaredPath = new HashMap();
    private Map webPutRefByVaredPath = new HashMap();
    private Map webDeleteRefByVaredPath = new HashMap();    
    
    // --------- WebRef Getters --------- //
    public WebRestRef getWebRestRef(RequestContext rc){
        return getWebRestRef(rc,null);
    }
    
    public WebRestRef getWebRestRef(RequestContext rc,String resourcePath){
        if (resourcePath == null){
            resourcePath = rc.getResourcePath();
        }
        HttpMethod method = rc.getMethod();
        
        WebRestRef ref = null;
        // first, check if there is a perfect match. 
        Map refByPath = getRefByPath(method);
        if (refByPath != null){
            ref = refByPath.get(resourcePath);
        }
        
        // if still null, check if there is a vared path matching
        if (ref == null){
            Map refByPattern = getRefByPattern(method);
            if(refByPattern != null){
                for (Pattern pattern : refByPattern.keySet()){
                    Matcher matcher = pattern.matcher(resourcePath);
                    if (matcher.matches()){
                        ref = refByPattern.get(pattern);
                        break;
                    }
                }
            }
        }
        
        return ref;
    }
    // --------- /WebRef Getters --------- //
    
    
    // --------- Register Methods (called in init only) --------- //
    public void registerWebRest(Class webClass, Method m, ParamDef[] paramDefs, HttpMethod method, String[] paths ){
        Map refByPath = getRefByPath(method);
        Map refByPattern = getRefByPattern(method);
        
        if (refByPath != null){
            WebRestRef ref = new WebRestRef(webClass,m, paramDefs);
            // if now paths, in the .value() then take the methodName as the path
            if (paths.length == 0){
                refByPath.put("/" + ref.getHandlerMethod().getName(), ref);
            }else{
                for (String path : paths){
                    if (path.indexOf("{") > -1){
                        Pair> patternAndMap = getPathPatternAndMap(path);
                        Pattern pattern = patternAndMap.getFirst();
                        WebRestRef varPathRef = new WebRestRef(webClass,m, paramDefs,pattern,patternAndMap.getSecond());
                        refByPattern.put(pattern,varPathRef);
                    }else{
                        refByPath.put(path, ref);
                    }
                    
                }     
            }
        }
    }
    
    
    // --------- /Register Methods (called in init only) --------- //
    private Pair> getPathPatternAndMap(String path){
        
        // --- find the var names --- //
        final String RGX_FIND_VAR =  "\\{(.*?)\\}";
        
        Pattern varFinderPattern = Pattern.compile(RGX_FIND_VAR);
        Matcher varFinderMatcher = varFinderPattern.matcher(path);
        
        Map paramNameByIdx = new HashMap();
        
        int group_idx = 0;
        StringBuilder pathRegExSb = new StringBuilder("^");
        String str = path;
        int str_idx = 0;
        while (varFinderMatcher.find()) {
            String paramName = varFinderMatcher.group();
            paramName = paramName.substring(1,paramName.length() -1);
            paramNameByIdx.put(group_idx, paramName);
            pathRegExSb.append(regexEscape(str.substring(str_idx, varFinderMatcher.start())));
            pathRegExSb.append("(.*?)");
            str_idx = varFinderMatcher.end();
            group_idx++;
        }
        pathRegExSb.append(regexEscape(str.substring(str_idx)));
        pathRegExSb.append("$");
        
        String pathRegEx = pathRegExSb.toString();
        Pattern pathPattern = Pattern.compile(pathRegEx);
        
        return new Pair>(pathPattern,paramNameByIdx);
    }
    
    static private String regexEscape(String str){
        return str.replace(".", "\\.");
    }    
    
    private Map getRefByPattern(HttpMethod httpMethod){
        switch (httpMethod){
            case GET: 
                return webGetRefByVaredPath;
            case POST: 
                return webPostRefByVaredPath;
            case PUT:
                return webPutRefByVaredPath;
            case DELETE:
                return webDeleteRefByVaredPath;
            default: 
                return null;
        }        
    }
    
    private Map getRefByPath(HttpMethod httpMethod){
        switch (httpMethod){
            case GET: 
                return webGetRefByPath;
            case POST: 
                return webPostRefByPath;
            case PUT:
                return webPutRefByPath;
            case DELETE:
                return webDeleteRefByPath;
            default: 
                return null;
        }        
    }
    


    
}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy