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

com.palantir.giraffe.file.base.attribute.AttributeMethodExtractor Maven / Gradle / Ivy

/**
 * Copyright 2015 Palantir Technologies, Inc.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */
package com.palantir.giraffe.file.base.attribute;

import static com.google.common.base.Preconditions.checkArgument;

import java.lang.reflect.Method;
import java.util.ArrayDeque;
import java.util.Arrays;
import java.util.Deque;
import java.util.HashMap;
import java.util.Map;

final class AttributeMethodExtractor {

    public static Map getters(Class type) {
        return find(type, Extractor.GETTER);
    }

    public static Map setters(Class type) {
        return find(type, Extractor.SETTER);
    }

    private enum Extractor {
        GETTER {
            @Override
            boolean isExtractable(Method method) {
                if (method.isAnnotationPresent(Attribute.class)) {
                    return isGetter(method);
                }
                return false;
            }

            @Override
            String getAttributeName(Method method) {
                String name = method.getAnnotation(Attribute.class).value();
                if (name.isEmpty()) {
                    name = method.getName();
                }
                return name;
            }
        },

        SETTER {
            @Override
            boolean isExtractable(Method method) {
                if (method.isAnnotationPresent(Attribute.class)) {
                    return isSetter(method);
                }
                return false;
            }

            @Override
            String getAttributeName(Method method) {
                String name = method.getAnnotation(Attribute.class).value();
                if (name.isEmpty()) {
                    name = stripSet(method);
                }
                return name;
            }

            private String stripSet(Method method) {
                String name = method.getName();
                checkArgument(!name.equals(SETTER_PREFIX),
                        "empty attribute name after processing %s",
                        method.getDeclaringClass().getName() + "." + method.getName());

                if (name.startsWith(SETTER_PREFIX)) {
                    name = name.substring(SETTER_PREFIX.length());
                    name = name.substring(0, 1).toLowerCase() + name.substring(1);
                }
                return name;
            }
        };

        abstract boolean isExtractable(Method method);
        abstract String getAttributeName(Method method);

        private static final String SETTER_PREFIX = "set";

        private static boolean isGetter(Method method) {
            return method.getParameterTypes().length == 0 && method.getReturnType() != Void.class;
        }

        private static boolean isSetter(Method method) {
            return method.getParameterTypes().length == 1;
        }
    }

    private static Map find(Class type, Extractor extractor) {
        Map result = new HashMap<>();

        Deque> hierarchy = new ArrayDeque<>();
        hierarchy.add(type);
        while (!hierarchy.isEmpty()) {
            Class current = hierarchy.removeFirst();
            for (Method method : current.getDeclaredMethods()) {
                if (extractor.isExtractable(method)) {
                    String name = extractor.getAttributeName(method);
                    if (!result.containsKey(name)) {
                        result.put(name, method);
                    }
                }
            }

            if (current.getSuperclass() != null) {
                hierarchy.add(current.getSuperclass());
            }
            hierarchy.addAll(Arrays.asList(current.getInterfaces()));
        }

        return result;
    }

    private AttributeMethodExtractor() {
        throw new UnsupportedOperationException();
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy