/*******************************************************************************
 * Copyright (c) 2011, 2017 Eurotech and/or its affiliates and others
 *
 * All rights reserved. This program and the accompanying materials
 * are made available under the terms of the Eclipse Public License v1.0
 * which accompanies this distribution, and is available at
 * http://www.eclipse.org/legal/epl-v10.html
 *
 * Contributors:
 *     Eurotech - initial API and implementation
 *     Red Hat Inc
 *******************************************************************************/
package org.eclipse.kapua.service.device.management.commons.call;

import org.eclipse.kapua.service.device.call.message.app.response.DeviceResponseMessage;
import org.eclipse.kapua.service.device.call.message.app.response.DeviceResponsePayload;
import org.eclipse.kapua.service.device.call.message.app.response.kura.KuraResponseCode;
import org.eclipse.kapua.service.device.management.commons.exception.DeviceManagementErrorCodes;
import org.eclipse.kapua.service.device.management.commons.exception.DeviceManagementException;

/**
 * Device application call response handler.<br>
 * This handler gets the call response from a device and convert it to the expected object type.
 *
 * @param <T>
 *            expected response type
 *
 * @since 1.0
 *
 */
public abstract class AbstractDeviceApplicationCallResponseHandler<T> {

    /**
     * Handle the device reply and convert it to the proper type
     *
     * @param responseMessage
     * @return
     * @throws DeviceManagementException
     */
    public T handle(DeviceResponseMessage<?, ?> responseMessage)
            throws DeviceManagementException {
        T responseObject = null;
        if (responseMessage != null) {
            DeviceResponsePayload responsePayload = responseMessage.getPayload();
            if (responsePayload != null) {
                KuraResponseCode responseCode = responsePayload.getResponseCode();

                switch (responseCode) {
                case ACCEPTED:
                    responseObject = handleAcceptedRequest(responseMessage);
                    break;
                case BAD_REQUEST: 
                    handleBadRequestReply(responseMessage);
                    //$FALL-THROUGH$
                case INTERNAL_ERROR:
                    handleDeviceInternalErrorReply(responseMessage);
                    //$FALL-THROUGH$
                case NOT_FOUND:
                    handleNotFoundReply(responseMessage);
                    //$FALL-THROUGH$
                }
            }
        }

        return responseObject;
    }

    /**
     * Handle an accepted request reply
     *
     * @param responseMessage
     * @return
     * @throws DeviceManagementException
     */
    protected abstract T handleAcceptedRequest(DeviceResponseMessage<?, ?> responseMessage)
            throws DeviceManagementException;

    /**
     * Handle a bad request reply
     *
     * @param responseMessage
     * @throws DeviceManagementException
     */
    protected void handleBadRequestReply(DeviceResponseMessage<?, ?> responseMessage)
            throws DeviceManagementException {
        DeviceResponsePayload responsePayload = responseMessage.getPayload();
        KuraResponseCode responseCode = responsePayload.getResponseCode();

        throw new DeviceManagementException(DeviceManagementErrorCodes.RESPONSE_BAD_REQUEST,
                null,
                new Object[] { responseCode,
                        responsePayload.getExceptionMessage(),
                        responsePayload.getExceptionStack() });
    }

    /**
     * Handle an internal error reply
     *
     * @param responseMessage
     * @throws DeviceManagementException
     */
    protected void handleDeviceInternalErrorReply(DeviceResponseMessage<?, ?> responseMessage)
            throws DeviceManagementException {
        DeviceResponsePayload responsePayload = responseMessage.getPayload();
        KuraResponseCode responseCode = responsePayload.getResponseCode();

        throw new DeviceManagementException(DeviceManagementErrorCodes.RESPONSE_INTERNAL_ERROR,
                null,
                new Object[] { responseCode,
                        responsePayload.getExceptionMessage(),
                        responsePayload.getExceptionStack() });
    }

    /**
     * Handle a resource not found reply
     *
     * @param responseMessage
     * @throws DeviceManagementException
     */
    protected void handleNotFoundReply(DeviceResponseMessage<?, ?> responseMessage)
            throws DeviceManagementException {
        DeviceResponsePayload responsePayload = responseMessage.getPayload();
        KuraResponseCode responseCode = responsePayload.getResponseCode();

        throw new DeviceManagementException(DeviceManagementErrorCodes.RESPONSE_NOT_FOUND,
                null,
                new Object[] { responseCode,
                        responsePayload.getExceptionMessage(),
                        responsePayload.getExceptionStack() });
    }

}

@@ -1682,41 +1682,8 @@
 n %7B%0A
-        T responseObject = null;%0A
     
@@ -1709,32 +1709,32 @@
 sage != null) %7B%0A
+
             Devi
@@ -2023,22 +2023,12 @@
   re
-sponseObject =
+turn
  han
@@ -2068,35 +2068,8 @@
 e);%0A
-                    break;%0A
     
@@ -2097,17 +2097,16 @@
 REQUEST:
- 
 %0A       
@@ -2178,32 +2178,22 @@
         
-//$FALL-THROUGH$
+break;
 %0A       
@@ -2311,32 +2311,22 @@
         
-//$FALL-THROUGH$
+break;
 %0A       
@@ -2432,24 +2432,14 @@
     
-//$FALL-THROUGH$
+break;
 %0A   
@@ -2497,22 +2497,12 @@
 urn 
-responseObject
+null
 ;%0A  

Switch to using "break" as sub-classes might now throw an exception