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

com.sdl.odata.processor.write.PostMethodHandler Maven / Gradle / Ivy

/**
 * Copyright (c) 2014-2024 All Rights Reserved by the RWS Group for and on behalf of its affiliates and subsidiaries.
 *
 * 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.sdl.odata.processor.write;

import com.sdl.odata.api.ODataBadRequestException;
import com.sdl.odata.api.ODataException;
import com.sdl.odata.api.edm.model.MetaType;
import com.sdl.odata.api.edm.model.Type;
import com.sdl.odata.api.parser.TargetType;
import com.sdl.odata.api.processor.ProcessorResult;
import com.sdl.odata.api.processor.datasource.DataSource;
import com.sdl.odata.api.processor.datasource.factory.DataSourceFactory;
import com.sdl.odata.api.processor.link.ODataLink;
import com.sdl.odata.api.processor.query.QueryResult;
import com.sdl.odata.api.service.ODataRequestContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.Map;

import static com.sdl.odata.api.service.ODataResponse.Status.CREATED;
import static com.sdl.odata.api.service.ODataResponse.Status.NO_CONTENT;

/**
 * Post Method Handler is specific to 'POST' operation.
 */
public class PostMethodHandler extends WriteMethodHandler {
    private static Logger log = LoggerFactory.getLogger(PostMethodHandler.class);

    public PostMethodHandler(ODataRequestContext requestContext, DataSourceFactory dataSourceFactory) {
        super(requestContext, dataSourceFactory);
    }

    @Override
    public ProcessorResult handleWrite(Object entity) throws ODataException {
        if (entity instanceof ODataLink) {
            return processLink((ODataLink) entity);
        } else {
            if (entity == null) {
                throw new ODataBadRequestException("The body of a POST request must contain a valid entity.");
            }

            return processEntity(entity);
        }
    }

    private ProcessorResult processEntity(Object entity) throws ODataException {
        TargetType targetType = getTargetType();
        if (targetType.isCollection()) {
            Type type = getEntityDataModel().getType(targetType.typeName());
            if (!MetaType.ENTITY.equals(type.getMetaType())) {
                throw new ODataBadRequestException("The body of a POST request must contain a valid entity.");
            }
            validateProperties(entity, getEntityDataModel());

            DataSource dataSource = getDataSource(type.getFullyQualifiedName());
            log.debug("Data source found for type '{}'", type.getFullyQualifiedName());

            // Get the location header before trying to create the entity
            Map headers = getResponseHeaders(entity);

            validateTargetType(entity);
            Object createdEntity = dataSource.create(getoDataUri(), entity, getEntityDataModel());
            if (isMinimalReturnPreferred()) {
                return new ProcessorResult(NO_CONTENT, headers);
            }
            return new ProcessorResult(CREATED, QueryResult.from(createdEntity), headers);
        } else {
            throw new ODataBadRequestException("The URI for a POST request should refer to a collection in which " +
                    "to create the entity, not to a single entity.");
        }
    }

    private ProcessorResult processLink(ODataLink link) throws ODataException {
        if (!link.getFromNavigationProperty().isCollection()) {
            throw new ODataBadRequestException("For a POST request to store an entity link, " +
                    "the referenced navigation " +
                    "property must be a collection navigation property. To set a link to a single value navigation " +
                    "property, use a PUT request instead. " +
                    "The navigation property: " + link.getFromNavigationProperty().getName() +
                    " in type: " + link.getFromEntityType().getFullyQualifiedName() + " is a single value.");
        }

        DataSource dataSource = getDataSource(link.fromEntityType().getFullyQualifiedName());
        dataSource.createLink(getoDataUri(), link, getEntityDataModel());

        return new ProcessorResult(NO_CONTENT);
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy