<commit_before>package com.zvoykish.restdl.adapters.partials;

import com.zvoykish.restdl.BasePartialAdapter;
import com.zvoykish.restdl.TypeHelper;
import com.zvoykish.restdl.objects.AnObject;
import com.zvoykish.restdl.objects.EndpointInfo;
import com.zvoykish.restdl.objects.TypedObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Created with IntelliJ IDEA.
 * User: Zvoykish
 * Date: 1/7/14
 * Time: 00:41
 */
@Component
public class PartialSpringMvcAdapter extends BasePartialAdapter {
    @Autowired
    private ApplicationContext context;

    private TypeHelper typeHelper;

    private String basePackage = System.getProperty("restdl.base.package");

    @Override
    public String getBasePackage() {
        return basePackage;
    }

    @Override
    public Collection<Class> getWebControllers() {
        Collection<Class> classes = new HashSet<>();
        Map<String, Object> controllerMap = context.getBeansWithAnnotation(Controller.class);
        for (Object controller : controllerMap.values()) {
            classes.add(controller.getClass());
        }
        controllerMap = context.getBeansWithAnnotation(RequestMapping.class);
        for (Object controller : controllerMap.values()) {
            classes.add(controller.getClass());
        }

        classes = new ArrayList<>(classes);
        Collections.sort((List<Class>) classes, new Comparator<Class>() {
            @Override
            public int compare(Class o1, Class o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        return classes;
    }

    @Override
    public String getControllerBaseUrl(Class<?> controllerClass) {
        String baseUrl = "";
        RequestMapping controllerMapping = controllerClass.getAnnotation(RequestMapping.class);
        if (controllerMapping != null) {
            String[] values = controllerMapping.value();
            if (values != null && values.length > 0) {
                baseUrl = values[0];
            }
        }
        return baseUrl;
    }

    @Override
    public String getMethodUrl(Method method) {
        String methodUrl = "";
        RequestMapping methodMapping = method.getAnnotation(RequestMapping.class);
        if (methodMapping != null) {
            String[] values = methodMapping.value();
            if (values != null && values.length > 0) {
                methodUrl = values[0];
            }
        }
        return methodUrl;
    }

    @Override
    public EndpointInfo.HttpMethod getMethodHttpMethod(Method method) {
        EndpointInfo.HttpMethod httpMethod = null;
        RequestMapping methodMapping = method.getAnnotation(RequestMapping.class);
        if (methodMapping != null) {
            RequestMethod[] requestMethods = methodMapping.method();
            if (requestMethods != null && requestMethods.length > 0) {
                httpMethod = EndpointInfo.HttpMethod.valueOf(requestMethods[0].name());
            }
        }
        return httpMethod;
    }

    @Override
    public List<AnObject> getMethodPathParams(Method method, Map<String, AtomicReference<TypedObject>> objects) {
        List<AnObject> pathParams = new ArrayList<>();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        Type[] parameterTypes = method.getGenericParameterTypes();
        if (parameterAnnotations != null && parameterAnnotations.length > 0) {
            for (int i = 0; i < parameterAnnotations.length; i++) {
                Annotation[] currAnns = parameterAnnotations[i];
                if (currAnns != null && currAnns.length > 0) {
                    for (Annotation annotation : currAnns) {
                        Type paramType = parameterTypes[i];
                        if (annotation instanceof PathVariable) {
                            PathVariable param = (PathVariable) annotation;
                            TypedObject type = typeHelper.typeToAType(paramType, objects);
                            // TODO: Support @PathVariable with no value, as it resolves to the param name...
                            pathParams.add(new AnObject(param.value(), type));
                        }
                    }
                }
            }
        }

        Collections.sort(pathParams, new Comparator<AnObject>() {
            @Override
            public int compare(AnObject o1, AnObject o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        return pathParams;
    }

    @Override
    public List<AnObject> getMethodQueryParams(Method method, Map<String, AtomicReference<TypedObject>> objects) {
        List<AnObject> queryParams = new ArrayList<>();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        Type[] parameterTypes = method.getGenericParameterTypes();
        if (parameterAnnotations != null && parameterAnnotations.length > 0) {
            for (int i = 0; i < parameterAnnotations.length; i++) {
                Annotation[] currAnns = parameterAnnotations[i];
                if (currAnns != null && currAnns.length > 0) {
                    for (Annotation annotation : currAnns) {
                        Type paramType = parameterTypes[i];
                        if (annotation instanceof RequestParam) {
                            RequestParam param = (RequestParam) annotation;
                            TypedObject type = typeHelper.typeToAType(paramType, objects);
                            // TODO: Support @RequestParam with no value, as it resolves to the param name...
                            queryParams.add(new AnObject(param.value(), type, param.defaultValue()));
                        }
                    }
                }
            }
        }

        Collections.sort(queryParams, new Comparator<AnObject>() {
            @Override
            public int compare(AnObject o1, AnObject o2) {
                return o1.getName().compareTo(o2.getName());
            }<commit_msg>Using Spring ASM for discovering variable names, impressed yet again with Spring's work!<commit_after>package com.zvoykish.restdl.adapters.partials;

import com.zvoykish.restdl.BasePartialAdapter;
import com.zvoykish.restdl.TypeHelper;
import com.zvoykish.restdl.objects.AnObject;
import com.zvoykish.restdl.objects.EndpointInfo;
import com.zvoykish.restdl.objects.TypedObject;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.ApplicationContext;
import org.springframework.core.LocalVariableTableParameterNameDiscoverer;
import org.springframework.core.ParameterNameDiscoverer;
import org.springframework.stereotype.Component;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;
import org.springframework.web.bind.annotation.*;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.lang.reflect.Type;
import java.util.*;
import java.util.concurrent.atomic.AtomicReference;

/**
 * Created with IntelliJ IDEA.
 * User: Zvoykish
 * Date: 1/7/14
 * Time: 00:41
 */
@Component
public class PartialSpringMvcAdapter extends BasePartialAdapter {
    @Autowired
    private ApplicationContext context;

    private TypeHelper typeHelper;

    private String basePackage = System.getProperty("restdl.base.package");
    private ParameterNameDiscoverer parameterNameDiscoverer;

    public PartialSpringMvcAdapter() {
        parameterNameDiscoverer = new LocalVariableTableParameterNameDiscoverer();
    }

    @Override
    public String getBasePackage() {
        return basePackage;
    }

    @Override
    public Collection<Class> getWebControllers() {
        Collection<Class> classes = new HashSet<>();
        Map<String, Object> controllerMap = context.getBeansWithAnnotation(Controller.class);
        for (Object controller : controllerMap.values()) {
            classes.add(controller.getClass());
        }
        controllerMap = context.getBeansWithAnnotation(RequestMapping.class);
        for (Object controller : controllerMap.values()) {
            classes.add(controller.getClass());
        }

        classes = new ArrayList<>(classes);
        Collections.sort((List<Class>) classes, new Comparator<Class>() {
            @Override
            public int compare(Class o1, Class o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        return classes;
    }

    @Override
    public String getControllerBaseUrl(Class<?> controllerClass) {
        String baseUrl = "";
        RequestMapping controllerMapping = controllerClass.getAnnotation(RequestMapping.class);
        if (controllerMapping != null) {
            String[] values = controllerMapping.value();
            if (values != null && values.length > 0) {
                baseUrl = values[0];
            }
        }
        return baseUrl;
    }

    @Override
    public String getMethodUrl(Method method) {
        String methodUrl = "";
        RequestMapping methodMapping = method.getAnnotation(RequestMapping.class);
        if (methodMapping != null) {
            String[] values = methodMapping.value();
            if (values != null && values.length > 0) {
                methodUrl = values[0];
            }
        }
        return methodUrl;
    }

    @Override
    public EndpointInfo.HttpMethod getMethodHttpMethod(Method method) {
        EndpointInfo.HttpMethod httpMethod = null;
        RequestMapping methodMapping = method.getAnnotation(RequestMapping.class);
        if (methodMapping != null) {
            RequestMethod[] requestMethods = methodMapping.method();
            if (requestMethods != null && requestMethods.length > 0) {
                httpMethod = EndpointInfo.HttpMethod.valueOf(requestMethods[0].name());
            }
        }
        return httpMethod;
    }

    @Override
    public List<AnObject> getMethodPathParams(Method method, Map<String, AtomicReference<TypedObject>> objects) {
        List<AnObject> pathParams = new ArrayList<>();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        Type[] parameterTypes = method.getGenericParameterTypes();
        String[] names = null;
        if (parameterAnnotations != null && parameterAnnotations.length > 0) {
            for (int i = 0; i < parameterAnnotations.length; i++) {
                Annotation[] currAnns = parameterAnnotations[i];
                if (currAnns != null && currAnns.length > 0) {
                    for (Annotation annotation : currAnns) {
                        Type paramType = parameterTypes[i];
                        if (annotation instanceof PathVariable) {
                            String paramName = ((PathVariable) annotation).value();
                            if (StringUtils.isEmpty(paramName)) {
                                if (names == null) {
                                    names = parameterNameDiscoverer.getParameterNames(method);
                                }
                                paramName = names[i];
                            }

                            TypedObject type = typeHelper.typeToAType(paramType, objects);
                            pathParams.add(new AnObject(paramName, type));
                        }
                    }
                }
            }
        }

        Collections.sort(pathParams, new Comparator<AnObject>() {
            @Override
            public int compare(AnObject o1, AnObject o2) {
                return o1.getName().compareTo(o2.getName());
            }
        });
        return pathParams;
    }

    @Override
    public List<AnObject> getMethodQueryParams(Method method, Map<String, AtomicReference<TypedObject>> objects) {
        List<AnObject> queryParams = new ArrayList<>();
        Annotation[][] parameterAnnotations = method.getParameterAnnotations();
        Type[] parameterTypes = method.getGenericParameterTypes();
        String[] names = null;
        if (parameterAnnotations != null && parameterAnnotations.length > 0) {
            for (int i = 0; i < parameterAnnotations.length; i++) {
                Annotation[] currAnns = parameterAnnotations[i];
                if (currAnns != null && currAnns.length > 0) {
                    for (Annotation annotation : currAnns) {
                        Type paramType = parameterTypes[i];
                        if (annotation instanceof RequestParam) {
                            RequestParam param = (RequestParam) annotation;
                            String paramName = param.value();
                            if (StringUtils.isEmpty(paramName)) {
                                if (names == null) {
                                    names = parameterNameDiscoverer.getParameterNames(method);
                                }
                                paramName = names[i];
                            }

                            TypedObject type = typeHelper.typeToAType(paramType, objects);
                            queryParams.add(new AnObject(paramName, type, param.defaultValue()));
                        }
                    }
                }
            }
        }

        Collections.sort(queryParams, new Comparator<AnObject>() {
            @Override
            public int compare(AnObject o1, AnObject o2) {
                return o1.getName().compareTo(o2.getName());
            }
{'fraction_non_alphanumeric': 0.09647092855076655, 'fraction_numerical': 0.0046282904252241824, 'mean_word_length': 2.1301493888637393, 'pattern_counts': {'":': 0, '<': 47, '<?xml version=': 0, '>': 57, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 4, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '3115067', 'n_tokens_mistral': 3423, 'n_tokens_neox': 3327, 'n_words': 739}