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

org.hibersap.mapping.AnnotationBapiMapper Maven / Gradle / Ivy

/*
 * Copyright (c) 2008-2017 akquinet tech@spree GmbH
 *
 * This file is part of Hibersap.
 *
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this software 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 org.hibersap.mapping;

import java.lang.reflect.Field;
import java.util.Set;
import org.hibersap.MappingException;
import org.hibersap.annotations.Bapi;
import org.hibersap.annotations.Parameter;
import org.hibersap.annotations.ThrowExceptionOnError;
import org.hibersap.mapping.model.BapiMapping;
import org.hibersap.mapping.model.ErrorHandling;
import org.hibersap.mapping.model.FieldMapping;
import org.hibersap.mapping.model.ParameterMapping;
import org.hibersap.mapping.model.StructureMapping;
import org.hibersap.mapping.model.TableMapping;
import static org.hibersap.mapping.ReflectionHelper.getDeclaredFieldsWithAnnotationRecursively;

/**
 * Creates a BAPI Mapping for Annotated classes.
 *
 * @author Carsten Erker
 */
public class AnnotationBapiMapper {

    private static final Class BAPI = Bapi.class;
    private static final Class PARAMETER = Parameter.class;

    /**
     * Takes an annotated BAPI class and creates a BapiMapping. The BapiMapping is used when a BAPI
     * gets executed to map SAP parameters to fields of the BAPI class.
     *
     * @param clazz The annotated Bapi class.
     * @return The BapiMapping
     */
    public BapiMapping mapBapi(final Class clazz) {
        assertIsBapiClass(clazz);

        Bapi bapiAnnotation = clazz.getAnnotation(BAPI);
        BapiMapping bapiMapping = new BapiMapping(clazz, bapiAnnotation.value(), getErrorHandling(clazz));

        Set fields = getDeclaredFieldsWithAnnotationRecursively(clazz, PARAMETER);
        for (Field field : fields) {
            addParameterToBapiMapping(bapiMapping, new BapiField(field));
        }
        return bapiMapping;
    }

    private void addParameterToBapiMapping(final BapiMapping bapiClass, final BapiField field) {
        if (field.isTable()) {
            bapiClass.addTableParameter(createTableMapping(field));
        } else {
            ParameterMapping mapping = createParameterMapping(field);
            if (field.isImport()) {
                bapiClass.addImportParameter(mapping);
            } else if (field.isExport()) {
                bapiClass.addExportParameter(mapping);
            } else {
                bapiClass.addChangingParameter(mapping);
            }
        }
    }

    private ParameterMapping createParameterMapping(final BapiField field) {
        if (field.isStructure()) {
            return createStructureMapping(field);
        } else if (field.isTableStructure()) {
            // nested table, annotated with IMPORT or EXPORT
            return createTableMapping(field);
        } else {
            return createFieldMapping(field);
        }
    }

    private void assertIsBapiClass(final Class clazz) {
        if (!clazz.isAnnotationPresent(BAPI)) {
            throw new MappingException("Class " + clazz.getName() + " is not annotated with @Bapi");
        }
    }

    private FieldMapping createFieldMapping(final BapiField field) {
        return new FieldMapping(field.getType(), field.getSapName(), field.getName(), field.getConverter());
    }

    private StructureMapping createStructureMapping(final BapiField structureField) {
        Class structureType = structureField.getAssociatedType();

        StructureMapping structureMapping = new StructureMapping(structureType, structureField.getSapName(),
                structureField.getName(), structureField.getConverter());

        final Set fields = getDeclaredFieldsWithAnnotationRecursively(structureType, PARAMETER);
        for (Field field : fields) {
            ParameterMapping paramMapping = createParameterMapping(new BapiField(field));
            structureMapping.addParameter(paramMapping);
        }
        return structureMapping;
    }

    private TableMapping createTableMapping(final BapiField field) {
        StructureMapping structureMapping = createStructureMapping(field);
        Class associatedType = field.getAssociatedType();
        if (associatedType == null) {
            throw new MappingException("The type of field " + field + " can not be detected.");
        }
        return new TableMapping(field.getType(), associatedType, field.getSapName(), field.getName(),
                structureMapping, field.getConverter());
    }

    private ErrorHandling getErrorHandling(final Class clazz) {
        String pathToReturnStructure = null;
        String[] errorMessageTypes = null;
        if (clazz.isAnnotationPresent(ThrowExceptionOnError.class)) {
            ThrowExceptionOnError annotation = clazz.getAnnotation(ThrowExceptionOnError.class);
            pathToReturnStructure = annotation.returnStructure();
            errorMessageTypes = annotation.errorMessageTypes();
        }
        return new ErrorHandling(pathToReturnStructure, errorMessageTypes);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy