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

com.github.aidensuen.mongo.reflection.ParamNameResolver Maven / Gradle / Ivy

There is a newer version: 1.1.2
Show newest version
package com.github.aidensuen.mongo.reflection;

import com.github.aidensuen.mongo.exception.BindingException;
import com.github.aidensuen.mongo.session.Configuration;
import org.springframework.core.*;
import org.springframework.data.domain.Pageable;
import org.springframework.data.repository.query.Param;

import java.lang.annotation.Annotation;
import java.lang.reflect.Method;
import java.util.*;

public class ParamNameResolver {

    private static final String GENERIC_NAME_PREFIX = "param";

    private static final ParameterNameDiscoverer DISCOVERER = new DefaultParameterNameDiscoverer();

    private final SortedMap names;

    private final SortedMap paramResolvableTypeSortedMap;

    private final Method method;

    private final Class implementationClass;

    private boolean hasParamAnnotation;

    public ParamNameResolver(Configuration config, Method method, Class implementationClass) {
        this.method = method;
        this.implementationClass = implementationClass;
        final Annotation[][] paramAnnotations = method.getParameterAnnotations();
        final SortedMap map = new TreeMap<>();
        final SortedMap map1 = new TreeMap<>();
        int paramCount = paramAnnotations.length;
        String[] paramNames = DISCOVERER.getParameterNames(method);
        // get names from @Param annotations
        for (int paramIndex = 0; paramIndex < paramCount; paramIndex++) {
            ResolvableType resolvableType = ResolvableType.forMethodParameter(method, paramIndex, implementationClass);
            map1.put(paramIndex, resolvableType);

            if (isSpecialParameter(resolvableType.resolve())) {
                // skip special parameters
                continue;
            }
            String name = null;
            for (Annotation annotation : paramAnnotations[paramIndex]) {
                if (annotation instanceof Param) {
                    hasParamAnnotation = true;
                    name = ((Param) annotation).value();
                }
            }
            if (name == null) {
                // @Param was not specified.
                if (config.isUseActualParamName()) {
                    name = paramNames != null ? paramNames[paramIndex] : null;
                }
                if (name == null) {
                    // use the parameter index as the name ("0", "1", ...)
                    // gcode issue #71
                    name = String.valueOf(map.size());
                }
            }
            map.put(paramIndex, name);
        }
        names = Collections.unmodifiableSortedMap(map);
        paramResolvableTypeSortedMap = Collections.unmodifiableSortedMap(map1);
    }

    public Method getMethod() {
        return method;
    }

    public ResolvableType getResolvableType(int paramIndex) {
        return paramResolvableTypeSortedMap.get(paramIndex);
    }

    public Class getImplementationClass() {
        return implementationClass;
    }

    public String[] getMethodClassNames() {
        List names = new ArrayList<>();
        names.add("-");
        for (ResolvableType resolvableType : paramResolvableTypeSortedMap.values()) {
            names.add(new ParamInfo(resolvableType).toString().toLowerCase().replaceAll("\\.", "/"));
            names.add("-");
        }
        names.remove(names.size() - 1);
        return names.toArray(new String[]{});
    }

    private static boolean isSpecialParameter(Class clazz) {
        return Pageable.class.isAssignableFrom(clazz);
    }

    public boolean hasParamAnnotation() {
        return hasParamAnnotation;
    }

    public String[] getNames() {
        return names.values().toArray(new String[0]);
    }

    public SortedMap getParamResolvableTypeSortedMap() {
        return paramResolvableTypeSortedMap;
    }

    public Object getNamedParams(Object[] args) {
        final int paramCount = names.size();
        if (args == null || paramCount == 0) {
            return null;
        } else if (!hasParamAnnotation && paramCount == 1) {
            return args[names.firstKey()];
        } else {
            final Map param = new ParamMap<>();
            int i = 0;
            for (Map.Entry entry : names.entrySet()) {
                param.put(entry.getValue(), args[entry.getKey()]);
                // add generic param names (param1, param2, ...)
                final String genericParamName = GENERIC_NAME_PREFIX + String.valueOf(i + 1);
                // ensure not to overwrite parameter named with @Param
                if (!names.containsValue(genericParamName)) {
                    param.put(genericParamName, args[entry.getKey()]);
                }
                i++;
            }
            return param;
        }
    }

    public static class ParamMap extends HashMap {

        private static final long serialVersionUID = -2212268410512043556L;

        @Override
        public V get(Object key) {
            if (!super.containsKey(key)) {
                throw new BindingException("Parameter '" + key + "' not found. Available parameters are " + keySet());
            }
            return super.get(key);
        }

    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy