/******************************************************************************* * Copyright (c) 2012-2017 Codenvy, S.A. * 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: * Codenvy, S.A. - initial API and implementation *******************************************************************************/ package org.eclipse.che.plugin.docker.compose.yaml.deserializer; import com.fasterxml.jackson.core.JsonParser; import com.fasterxml.jackson.core.JsonProcessingException; import com.fasterxml.jackson.databind.DeserializationContext; import com.fasterxml.jackson.databind.JsonDeserializer; import java.io.IOException; import java.util.HashMap; import java.util.List; import java.util.Map; import static java.lang.String.format; /** * Deserializer of environment section of Docker compose file. * * @author Dmytro Nochevnov */ public class EnvironmentDeserializer extends JsonDeserializer<Map<String, String>> { public static final String ARRAY_ITEM_VALUE_DIVIDER = "="; public static final String UNSUPPORTED_VALUE_MESSAGE = "Unsupported value '%s'."; @Override public Map<String, String> deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException { Object environment = jsonParser.readValueAs(Object.class); /* Parse dictionary in view of: "environment: key1: value1 key2: value2" */ if (environment instanceof Map) { return (Map<String, String>) environment; } /* Parse array in view of: "environment: - key1=value1 - key2=value2" */ try { if (environment instanceof List) { return parseArrayEnvironment((List<String>) environment); } } catch (IllegalArgumentException ie) { throw ctxt.mappingException(ie.getMessage()); } catch (Exception e) { throw ctxt.mappingException(format(UNSUPPORTED_VALUE_MESSAGE, environment)); } // work around empty environment if (environment instanceof String) { if (((String) environment).isEmpty()) { return new HashMap<>(); } throw ctxt.mappingException(format(UNSUPPORTED_VALUE_MESSAGE, environment)); } /* Work around unsupported type of environment content, for example, 'Boolean' in case of content: "environment: true" */ throw ctxt.mappingException(format("Unsupported type '%s'.", environment.getClass())); } /** * Convert list [key1=value1, key2=value2] into Map<String, String>{ key1: value1, key2: value2 }. * * @param environment * list form of compose environment to parse * @return map of key/value which are divided by "=" sign in item. * @throws IllegalArgumentException if there is no "=" sign in environment item, or if there is empty key in item */ private Map<String, String> parseArrayEnvironment(List<String> environment) throws IllegalArgumentException { Map<String, String> map = new HashMap<>(); for (String item : environment) { int valueDividerIndex = item.indexOf(ARRAY_ITEM_VALUE_DIVIDER); if (valueDividerIndex < 1) { throw new IllegalArgumentException(format(UNSUPPORTED_VALUE_MESSAGE, item)); } String key = item.substring(0, valueDividerIndex); String value = item.substring(valueDividerIndex + 1, item.length()); map.put(key, value); } return map; } }