org.sentilo.platform.server.handler.impl.CatalogAlertHandler.java Source code

Java tutorial

Introduction

Here is the source code for org.sentilo.platform.server.handler.impl.CatalogAlertHandler.java

Source

/*
 * Sentilo
 * 
 * Copyright (C) 2013 Institut Municipal dInformtica, Ajuntament de Barcelona.
 * 
 * This program is licensed and may be used, modified and redistributed under the terms of the
 * European Public License (EUPL), either version 1.1 or (at your option) any later version as soon
 * as they are approved by the European Commission.
 * 
 * Alternatively, you may redistribute and/or modify this program under the terms of the GNU Lesser
 * General Public License as published by the Free Software Foundation; either version 3 of the
 * License, or (at your option) any later version.
 * 
 * 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 licenses for the specific language governing permissions, limitations and more details.
 * 
 * You should have received a copy of the EUPL1.1 and the LGPLv3 licenses along with this program;
 * if not, you may find them at:
 * 
 * https://joinup.ec.europa.eu/software/page/eupl/licence-eupl http://www.gnu.org/licenses/ and
 * https://www.gnu.org/licenses/lgpl.txt
 */
package org.sentilo.platform.server.handler.impl;

import java.util.List;

import org.sentilo.common.domain.CatalogAlert;
import org.sentilo.common.domain.CatalogAlertInputMessage;
import org.sentilo.common.domain.CatalogResponseMessage;
import org.sentilo.platform.common.exception.PlatformException;
import org.sentilo.platform.common.service.CatalogService;
import org.sentilo.platform.server.exception.CatalogErrorException;
import org.sentilo.platform.server.exception.ForbiddenAccessException;
import org.sentilo.platform.server.handler.AbstractHandler;
import org.sentilo.platform.server.parser.CatalogAlertParser;
import org.sentilo.platform.server.request.SentiloRequest;
import org.sentilo.platform.server.response.SentiloResponse;
import org.sentilo.platform.server.validation.CatalogAlertValidator;
import org.sentilo.platform.server.validation.RequestMessageValidator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Controller;
import org.springframework.util.StringUtils;

import com.google.common.base.Function;
import com.google.common.collect.Multimap;
import com.google.common.collect.Multimaps;

@Controller
public class CatalogAlertHandler extends AbstractHandler {

    private final Logger logger = LoggerFactory.getLogger(CatalogAlertHandler.class);

    @Autowired
    private CatalogService catalogService;

    private CatalogAlertParser parser = new CatalogAlertParser();
    private RequestMessageValidator<CatalogAlertInputMessage> validator = new CatalogAlertValidator();

    @Override
    public void onDelete(final SentiloRequest request, final SentiloResponse response) throws PlatformException {
        logger.debug("Executing catalog alert DELETE request");
        debug(request);

        doRealOnDelete(request, false);
    }

    @Override
    public void onGet(final SentiloRequest request, final SentiloResponse response) throws PlatformException {
        logger.debug("Executing catalog alert GET request");
        debug(request);

        // La peticion slo puede ser de la siguiente manera
        // GET /catalog/alert/<entity>
        // Ademas, puede haber parametros en la URL con los cuales filtrar las alertas a retornar

        validateResourceNumberParts(request, 0, 1);
        final CatalogAlertInputMessage inputMessage = parser.parseGetRequest(request);
        validator.validateRequestMessageOnGet(inputMessage);
        validateAdminAcess(request.getEntitySource(), inputMessage.getEntityId());

        // Aqui no tiene sentido hacer ninguna validacin de autorizacion ya que se aplica sobre la
        // misma entidad que hace la peticion
        final CatalogResponseMessage responseMessage = catalogService.getAuthorizedAlerts(inputMessage);
        checkCatalogResponseMessage(responseMessage);

        parser.writeResponse(request, response, responseMessage);
    }

    @Override
    public void onPost(final SentiloRequest request, final SentiloResponse response) throws PlatformException {
        logger.debug("Executing catalog alert POST request");
        debug(request);

        // La peticion slo puede ser de la siguiente manera
        // POST /catalog/alert/<entity>

        validateResourceNumberParts(request, 0, 1);
        final CatalogAlertInputMessage inputMessage = parser.parsePostRequest(request);
        validator.validateRequestMessageOnPost(inputMessage);
        validateAdminAcess(request.getEntitySource(), inputMessage.getEntityId());
        validateAuthorization(inputMessage, request);

        // Redirigir peticion al catlogo --> Cliente REST para el catlogo.
        final CatalogResponseMessage responseMessage = catalogService.insertAlerts(inputMessage);
        checkCatalogResponseMessage(responseMessage);
    }

    @Override
    public void onPut(final SentiloRequest request, final SentiloResponse response) throws PlatformException {
        logger.debug("Executing catalog alert PUT request");
        debug(request);

        final String method = request.getRequestParameter("method");
        if (StringUtils.hasText(method) && method.equals("delete")) {
            doRealOnDelete(request, true);
        } else {
            doRealOnPut(request);
        }

    }

    private void doRealOnDelete(final SentiloRequest request, final boolean simulate) throws PlatformException {
        logger.debug("Executing catalog alert DELETE request");
        debug(request);

        // La peticion slo puede ser de la siguiente manera
        // DELETE /catalog/alert/<entity>

        validateResourceNumberParts(request, 0, 1);
        final CatalogAlertInputMessage inputMessage = parser.parseDeleteRequest(request, simulate);
        validator.validateRequestMessageOnDelete(inputMessage);
        validateAdminAcess(request.getEntitySource(), inputMessage.getEntityId());

        final CatalogResponseMessage responseMessage = catalogService.deleteAlerts(inputMessage);
        checkCatalogResponseMessage(responseMessage);

    }

    private void doRealOnPut(final SentiloRequest request) throws PlatformException {
        logger.debug("Executing catalog alert PUT request");
        debug(request);

        // La peticion slo puede ser de la sigiente manera
        // PUT /catalog/alert/<entity>

        validateResourceNumberParts(request, 0, 1);
        final CatalogAlertInputMessage inputMessage = parser.parsePutRequest(request);
        validator.validateRequestMessageOnPut(inputMessage);
        validateAdminAcess(request.getEntitySource(), inputMessage.getEntityId());
        validateAuthorization(inputMessage, request);

        final CatalogResponseMessage responseMessage = catalogService.updateAlerts(inputMessage);
        checkCatalogResponseMessage(responseMessage);
    }

    protected void validateAuthorization(final CatalogAlertInputMessage inputMessage, final SentiloRequest request)
            throws ForbiddenAccessException {
        // Internal alerts only could be inserted/updated by catalog entity
        final Multimap<String, CatalogAlert> groups = groupAlertsByType(inputMessage.getAlerts());
        if (groups.get("INTERNAL").size() > 0 && !getCatalogId().equals(request.getEntitySource())) {
            final String errorMessage = String.format("You are not authorized to insert/update internal alerts.");
            throw new ForbiddenAccessException(errorMessage);
        }
    }

    /**
     * Group alerts list by type (INTERNAL or EXTERNAL)
     * 
     * @param alerts
     * @return
     */
    protected Multimap<String, CatalogAlert> groupAlertsByType(final List<CatalogAlert> alerts) {
        final Function<CatalogAlert, String> internalFunction = new Function<CatalogAlert, String>() {

            @Override
            public String apply(final CatalogAlert alert) {
                // alert type could be null if it is wrong, so return empty string if it is null
                return (alert.getType() != null ? alert.getType() : "");
            }
        };
        return Multimaps.index(alerts, internalFunction);
    }

    private void checkCatalogResponseMessage(final CatalogResponseMessage responseMessage)
            throws CatalogErrorException {
        if (!responseMessage.getCode().equals(CatalogResponseMessage.OK)) {
            throw new CatalogErrorException(responseMessage.getCode(), responseMessage.getErrorMessage(),
                    responseMessage.getErrorDetails());
        }
    }
}