blob: 09195e397daa22126cb454ddb8080fb3dfd33269 [file] [log] [blame]
/*******************************************************************************
* Copyright (C) 2021 the Eclipse BaSyx Authors
*
* This program and the accompanying materials are made
* available under the terms of the Eclipse Public License 2.0
* which is available at https://www.eclipse.org/legal/epl-2.0/
*
* SPDX-License-Identifier: EPL-2.0
******************************************************************************/
package org.eclipse.basyx.vab.coder.json.metaprotocol;
import java.util.Collection;
import java.util.Map;
import org.eclipse.basyx.vab.coder.json.serialization.DefaultTypeFactory;
import org.eclipse.basyx.vab.coder.json.serialization.GSONTools;
import org.eclipse.basyx.vab.coder.json.serialization.GSONToolsFactory;
import org.eclipse.basyx.vab.exception.provider.ProviderException;
import org.eclipse.basyx.vab.protocol.http.server.ExceptionToHTTPCodeMapper;
public class MetaprotocolHandler implements IMetaProtocolHandler {
/**
* Reference to serializer / deserializer
*/
protected GSONTools serializer = null;
/**
* Constructor that create the serializer
*
*/
public MetaprotocolHandler() {
// Create GSON serializer
serializer = new GSONTools(new DefaultTypeFactory());
}
/**
* Constructor that accepts specific factory for serializer
* @param factory
*/
public MetaprotocolHandler(GSONToolsFactory factory) {
// Create GSON serializer
serializer = new GSONTools(factory);
}
@Override
@SuppressWarnings("unchecked")
public Object deserialize(String message) throws ProviderException {
// First get the GSON object from the JSON string
Object gsonObj = serializer.deserialize(message);
// Then interpret and verify the result object
Object result = null;
// If it is a map, see if it does contain an exception
if (gsonObj instanceof Map) {
Map<String, Object> responseMap = (Map<String, Object>) gsonObj;
// Handle meta information and exceptions
result = handleResult(responseMap);
} else {
// Otherwise, return directly.
result = gsonObj;
}
return result;
}
/**
* Verify the Result and try to extract the entity if available. Process
* information of "success", "entityType" and "messages"
*
* @param responseMap
* - provide deserialized message
* @return
*/
@SuppressWarnings("unchecked")
private Object handleResult(Map<String, Object> responseMap) throws ProviderException {
// If there's no success: "false", there was no exception
if (!responseMap.containsKey(Result.SUCCESS)) {
return responseMap;
}
// Retrieve messages if any
Collection<Map<String, Object>> messages = (Collection<Map<String, Object>>) responseMap.get(Result.MESSAGES);
if (messages == null) {
throw new ProviderException("Unknown error occured: Success entry is indicating an error but no message was attached");
}
Map<String, Object> first = messages.iterator().next(); // assumes an Exception always comes with a message
// Get the code of the exception message
String code = (String) first.get(Message.CODE);
// Get the text from the exception
String text = (String) first.get(Message.TEXT);
throw getExceptionFromCode(code, text);
}
/**
* Creates a ProviderException from a String received form the Server</br>
* The String has to be formated e.g. "ResourceNotFoundException: Requested Item
* was not found"
*
* @param code - code of the exception message
* @return the matching ProviderException
*/
public static ProviderException getExceptionFromCode(String code, String text) {
int exceptionCode = Integer.parseInt(code);
// return exception based on code
return ExceptionToHTTPCodeMapper.mapToException(exceptionCode, text);
}
}