/*******************************************************************************
* 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.core.TreeNode;
import com.fasterxml.jackson.databind.DeserializationContext;
import com.fasterxml.jackson.databind.JsonDeserializer;
import com.fasterxml.jackson.databind.JsonMappingException;
import com.fasterxml.jackson.databind.node.ArrayNode;
import com.fasterxml.jackson.databind.node.TextNode;
import org.eclipse.che.plugin.docker.compose.ComposeServiceImpl;
import org.eclipse.che.plugin.docker.compose.yaml.ComposeEnvironmentParser;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import static java.lang.String.format;
import static java.util.Arrays.asList;
/**
* Custom deserializer for parsing {@link ComposeServiceImpl#command}
* to list command words in the yaml compose file.
* <p>Command can be:</p>
* <ul>
* <li>string array:</li>
*
* <pre>
* image: codenvy/mysql
* environment:
* MYSQL_USER: petclinic
* MYSQL_PASSWORD: password
* mem_limit: 2147483648
* command: [service, mysql, start]
* </pre>
*
* <li>simple string line:</li>
*
* <pre>
* image: codenvy/mysql
* environment:
* MYSQL_USER: petclinic
* MYSQL_PASSWORD: password
* mem_limit: 2147483648
* command: service mysql start
* </pre>
* </ul>
*
*
* See more for parsing compose file
* {@link ComposeEnvironmentParser}.
* <p>Note: this deserializer works for json too.</p>
*
* @author Alexander Andrienko
*/
public class CommandDeserializer extends JsonDeserializer<List<String>> {
private static final String SPLIT_COMMAND_REGEX = "[ \n\r]+";
/**
* Parse command field from the compose yaml file to list command words.
*
* @param jsonParser
* json parser
* @param ctxt
* deserialization context
* @throws IOException
* in case I/O error. For example element to parsing contains
* invalid yaml field type defined for this field by yaml document model.
* @throws JsonProcessingException
*/
@Override
public List<String> deserialize(JsonParser jsonParser, DeserializationContext ctxt) throws IOException, JsonProcessingException {
TreeNode tree = jsonParser.readValueAsTree();
if (tree.isArray()) {
return toCommand((ArrayNode)tree, ctxt);
}
if (tree instanceof TextNode) {
TextNode textNode = (TextNode)tree;
return asList(textNode.asText().trim().split(SPLIT_COMMAND_REGEX));
}
throw ctxt.mappingException((format("Field '%s' must be simple text or string array.", jsonParser.getCurrentName())));
}
private List<String> toCommand(ArrayNode arrayCommandNode, DeserializationContext ctxt) throws JsonMappingException {
List<String> commands = new ArrayList<>();
for (TreeNode treeNode : arrayCommandNode) {
if (treeNode instanceof TextNode) {
TextNode textNode = (TextNode)treeNode;
commands.add(textNode.asText());
} else {
throw ctxt.mappingException("Array 'command' contains not string element.");
}
}
return commands;
}
}