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

capital.scalable.restdocs.request.AbstractParameterSnippet Maven / Gradle / Ivy

The newest version!
/*-
 * #%L
 * Spring Auto REST Docs Core
 * %%
 * Copyright (C) 2015 - 2021 Scalable Capital GmbH
 * %%
 * 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.
 * #L%
 */
package capital.scalable.restdocs.request;

import static capital.scalable.restdocs.OperationAttributeHelper.getConstraintReader;
import static capital.scalable.restdocs.OperationAttributeHelper.getHandlerMethod;
import static capital.scalable.restdocs.OperationAttributeHelper.getJavadocReader;
import static capital.scalable.restdocs.OperationAttributeHelper.getTranslationResolver;
import static capital.scalable.restdocs.constraints.ConstraintReader.CONSTRAINTS_ATTRIBUTE;
import static capital.scalable.restdocs.constraints.ConstraintReader.DEFAULT_VALUE_ATTRIBUTE;
import static capital.scalable.restdocs.constraints.ConstraintReader.DEPRECATED_ATTRIBUTE;
import static capital.scalable.restdocs.constraints.ConstraintReader.OPTIONAL_ATTRIBUTE;
import static capital.scalable.restdocs.util.FieldDescriptorUtil.assertAllDocumented;
import static capital.scalable.restdocs.util.TypeUtil.determineTypeName;
import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import static org.springframework.restdocs.payload.PayloadDocumentation.fieldWithPath;
import static org.springframework.util.StringUtils.hasLength;

import java.lang.annotation.Annotation;
import java.util.Map;

import capital.scalable.restdocs.constraints.ConstraintReader;
import capital.scalable.restdocs.i18n.SnippetTranslationResolver;
import capital.scalable.restdocs.jackson.DeprecatedAttribute;
import capital.scalable.restdocs.jackson.FieldDescriptors;
import capital.scalable.restdocs.javadoc.JavadocReader;
import capital.scalable.restdocs.section.SectionSupport;
import capital.scalable.restdocs.snippet.StandardTableSnippet;
import org.springframework.core.MethodParameter;
import org.springframework.restdocs.operation.Operation;
import org.springframework.restdocs.payload.FieldDescriptor;
import org.springframework.restdocs.snippet.Attributes.Attribute;
import org.springframework.web.bind.annotation.ValueConstants;
import org.springframework.web.method.HandlerMethod;

abstract class AbstractParameterSnippet extends StandardTableSnippet
        implements SectionSupport {
    protected AbstractParameterSnippet(String snippetName, Map attributes) {
        super(snippetName, attributes);
    }

    @Override
    protected FieldDescriptors createFieldDescriptors(Operation operation,
            HandlerMethod handlerMethod) {
        JavadocReader javadocReader = getJavadocReader(operation);
        SnippetTranslationResolver translationResolver = getTranslationResolver(operation);
        ConstraintReader constraintReader = getConstraintReader(operation);

        FieldDescriptors fieldDescriptors = new FieldDescriptors();
        for (MethodParameter param : handlerMethod.getMethodParameters()) {
            A annot = getAnnotation(param);
            if (annot != null) {
                addFieldDescriptor(handlerMethod, javadocReader, constraintReader, fieldDescriptors,
                        param, annot);
            }
        }

        if (shouldFailOnUndocumentedParams()) {
            assertAllDocumented(fieldDescriptors.values(), translationResolver.translate(getHeaderKey(operation)).toLowerCase());
        }

        return fieldDescriptors;
    }

    private void addFieldDescriptor(HandlerMethod handlerMethod,
            JavadocReader javadocReader, ConstraintReader constraintReader,
            FieldDescriptors fieldDescriptors, MethodParameter param, A annot) {
        String javaParameterName = param.getParameterName();
        String pathName = getPath(annot);

        String parameterName = hasLength(pathName) ? pathName : javaParameterName;
        String parameterTypeName = determineTypeName(param.nestedIfOptional().getNestedParameterType());
        String description = javadocReader.resolveMethodParameterComment(
                handlerMethod.getBeanType(), handlerMethod.getMethod().getName(),
                javaParameterName);

        FieldDescriptor descriptor = fieldWithPath(parameterName)
                .type(parameterTypeName)
                .description(description);

        Attribute constraints = constraintAttribute(param, constraintReader);
        Attribute optionals = optionalsAttribute(param, annot);
        Attribute deprecated = deprecatedAttribute(param, annot, javadocReader);
        final Attribute defaultValue = defaultValueAttribute(annot);
        if (defaultValue == null) {
            descriptor.attributes(constraints, optionals, deprecated);
        } else {
            descriptor.attributes(constraints, optionals, deprecated, defaultValue);
        }

        fieldDescriptors.putIfAbsent(parameterName, descriptor);
    }

    abstract protected String getDefaultValue(A annotation);

    protected boolean isCustomDefaultValue(final String defaultValue) {
        return defaultValue != null && !ValueConstants.DEFAULT_NONE.equals(defaultValue);
    }

    protected Attribute constraintAttribute(MethodParameter param,
            ConstraintReader constraintReader) {
        return new Attribute(CONSTRAINTS_ATTRIBUTE, constraintReader.getConstraintMessages(param));
    }

    protected Attribute optionalsAttribute(MethodParameter param, A annot) {
        return new Attribute(OPTIONAL_ATTRIBUTE, singletonList(!isRequired(param, annot)));
    }

    protected Attribute deprecatedAttribute(MethodParameter param, A annot,
            JavadocReader javadocReader) {
        return new Attribute(DEPRECATED_ATTRIBUTE,
                new DeprecatedAttribute(param.getParameterAnnotation(Deprecated.class) != null, emptyList()));
    }

    protected Attribute defaultValueAttribute(A annot) {
        final String defaultValue = getDefaultValue(annot);

        return isCustomDefaultValue(defaultValue) ?
                new Attribute(DEFAULT_VALUE_ATTRIBUTE, defaultValue) : null;
    }

    protected abstract boolean isRequired(MethodParameter param, A annot);

    protected abstract String getPath(A annot);

    abstract A getAnnotation(MethodParameter param);

    protected abstract boolean shouldFailOnUndocumentedParams();

    @Override
    public String getFileName() {
        return getSnippetName();
    }

    @Override
    public boolean hasContent(Operation operation) {
        for (MethodParameter param : getHandlerMethod(operation).getMethodParameters()) {
            A annot = getAnnotation(param);
            if (annot != null) {
                return true;
            }
        }
        return false;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy