001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and contributors.
003 *
004 * All rights reserved. This program and the accompanying materials
005 * are made available under the terms of the GNU Lesser General Public License
006 * (LGPL) version 2.1 which accompanies this distribution, and is available at
007 * http://www.gnu.org/licenses/lgpl-2.1.html
008 *
009 * This library is distributed in the hope that it will be useful,
010 * but WITHOUT ANY WARRANTY; without even the implied warranty of
011 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
012 * Lesser General Public License for more details.
013 *
014 * Contributors:
015 *     Anahide Tchertchian
016 */
017package org.nuxeo.ecm.automation.io.yaml;
018
019import static org.nuxeo.ecm.automation.core.Constants.T_PROPERTIES;
020
021import java.io.IOException;
022import java.util.HashMap;
023import java.util.LinkedHashMap;
024import java.util.List;
025import java.util.Map;
026
027import org.nuxeo.ecm.automation.OperationDocumentation;
028import org.nuxeo.ecm.automation.OperationDocumentation.Param;
029import org.nuxeo.ecm.automation.core.OperationChainContribution;
030import org.nuxeo.ecm.automation.core.OperationChainContribution.Operation;
031import org.nuxeo.ecm.automation.core.util.Properties;
032import org.yaml.snakeyaml.nodes.Node;
033import org.yaml.snakeyaml.nodes.Tag;
034import org.yaml.snakeyaml.representer.Represent;
035import org.yaml.snakeyaml.representer.Representer;
036
037/**
038 * YAML representer for automation chains.
039 *
040 * @since 5.9.4
041 */
042public class YamlAutomationRepresenter extends Representer {
043
044    public YamlAutomationRepresenter() {
045        super();
046        this.addClassTag(OperationDocumentation.class, Tag.MAP);
047        this.representers.put(OperationDocumentation.class, new ChainRepr());
048        this.addClassTag(Operation.class, Tag.MAP);
049        this.representers.put(Operation.class, new OpRepr());
050        this.addClassTag(Param.class, Tag.MAP);
051        this.representers.put(Param.class, new ParamRepr());
052    }
053
054    public class ChainRepr implements Represent {
055        @Override
056        public Node representData(Object data) {
057            OperationDocumentation c = (OperationDocumentation) data;
058            Tag tag = getTag(OperationDocumentation.class, null);
059            Map<Object, Object> mapping = new LinkedHashMap<Object, Object>();
060            if (c.getDescription() != null) {
061                mapping.put("description", c.getDescription());
062            }
063            if (c.getParams() != null && c.getParams().length != 0) {
064                mapping.put("params", c.getParams());
065            }
066            Operation[] ops = c.getOperations();
067            if (ops != null && ops.length != 0) {
068                if (mapping.isEmpty()) {
069                    // omit the "operations" parent if params and description
070                    // are empty
071                    return YamlAutomationRepresenter.this.representData(ops);
072                }
073                mapping.put("operations", ops);
074            }
075            return representMapping(tag, mapping, null);
076        }
077    }
078
079    public class OpRepr implements Represent {
080
081        @Override
082        public Node representData(Object data) {
083            Operation op = (Operation) data;
084            Tag tag = getTag(Operation.class, null);
085            List<OperationChainContribution.Param> params = op.getParams();
086            if (params != null && !params.isEmpty()) {
087                Map<Object, Object> mapping = new HashMap<Object, Object>();
088                Map<Object, Object> subs = new LinkedHashMap<Object, Object>();
089                for (OperationChainContribution.Param param : params) {
090                    // handle java properties use case
091                    if (T_PROPERTIES.equals(param.getType())) {
092                        if (param.getMap() != null && !param.getMap().isEmpty()) {
093                            Properties props = new Properties(param.getMap());
094                            subs.put(param.getName(), props);
095                        } else {
096                            try {
097                                Properties props = new Properties(param.getValue());
098                                subs.put(param.getName(), props);
099                            } catch (IOException e) {
100                                subs.put(param.getName(), param.getValue());
101                            }
102                        }
103                    } else {
104                        subs.put(param.getName(), param.getValue());
105                    }
106                }
107                mapping.put(op.getId(), subs);
108                return representMapping(tag, mapping, null);
109            } else {
110                return YamlAutomationRepresenter.this.representData(op.getId());
111            }
112        }
113    }
114
115    public class ParamRepr implements Represent {
116        @Override
117        public Node representData(Object data) {
118            Param p = (Param) data;
119            Tag tag = getTag(Param.class, null);
120            Map<Object, Object> mapping = new HashMap<Object, Object>();
121            Map<Object, Object> subs = new LinkedHashMap<Object, Object>();
122            subs.put("type", p.getType());
123            if (p.getDescription() != null) {
124                subs.put("description", p.getDescription());
125            }
126            if (p.getValues() != null && p.getValues().length != 0) {
127                subs.put("values", p.getValues());
128            }
129            mapping.put(p.getName(), subs);
130            return representMapping(tag, mapping, null);
131        }
132    }
133
134}