001/*
002 * (C) Copyright 2014 Nuxeo SA (http://nuxeo.com/) and others.
003 *
004 * Licensed under the Apache License, Version 2.0 (the "License");
005 * you may not use this file except in compliance with the License.
006 * You may obtain a copy of the License at
007 *
008 *     http://www.apache.org/licenses/LICENSE-2.0
009 *
010 * Unless required by applicable law or agreed to in writing, software
011 * distributed under the License is distributed on an "AS IS" BASIS,
012 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
013 * See the License for the specific language governing permissions and
014 * limitations under the License.
015 *
016 * Contributors:
017 *     Anahide Tchertchian
018 */
019package org.nuxeo.ecm.automation.io.yaml;
020
021import static org.nuxeo.ecm.automation.core.Constants.T_PROPERTIES;
022
023import java.io.IOException;
024import java.util.HashMap;
025import java.util.LinkedHashMap;
026import java.util.List;
027import java.util.Map;
028
029import org.nuxeo.ecm.automation.OperationDocumentation;
030import org.nuxeo.ecm.automation.OperationDocumentation.Param;
031import org.nuxeo.ecm.automation.core.OperationChainContribution;
032import org.nuxeo.ecm.automation.core.OperationChainContribution.Operation;
033import org.nuxeo.ecm.automation.core.util.Properties;
034import org.yaml.snakeyaml.nodes.Node;
035import org.yaml.snakeyaml.nodes.Tag;
036import org.yaml.snakeyaml.representer.Represent;
037import org.yaml.snakeyaml.representer.Representer;
038
039/**
040 * YAML representer for automation chains.
041 *
042 * @since 5.9.4
043 */
044public class YamlAutomationRepresenter extends Representer {
045
046    public YamlAutomationRepresenter() {
047        super();
048        this.addClassTag(OperationDocumentation.class, Tag.MAP);
049        this.representers.put(OperationDocumentation.class, new ChainRepr());
050        this.addClassTag(Operation.class, Tag.MAP);
051        this.representers.put(Operation.class, new OpRepr());
052        this.addClassTag(Param.class, Tag.MAP);
053        this.representers.put(Param.class, new ParamRepr());
054    }
055
056    public class ChainRepr implements Represent {
057        @Override
058        public Node representData(Object data) {
059            OperationDocumentation c = (OperationDocumentation) data;
060            Tag tag = getTag(OperationDocumentation.class, null);
061            Map<Object, Object> mapping = new LinkedHashMap<Object, Object>();
062            if (c.getDescription() != null) {
063                mapping.put("description", c.getDescription());
064            }
065            if (c.getParams() != null && c.getParams().length != 0) {
066                mapping.put("params", c.getParams());
067            }
068            Operation[] ops = c.getOperations();
069            if (ops != null && ops.length != 0) {
070                if (mapping.isEmpty()) {
071                    // omit the "operations" parent if params and description
072                    // are empty
073                    return YamlAutomationRepresenter.this.representData(ops);
074                }
075                mapping.put("operations", ops);
076            }
077            return representMapping(tag, mapping, null);
078        }
079    }
080
081    public class OpRepr implements Represent {
082
083        @Override
084        public Node representData(Object data) {
085            Operation op = (Operation) data;
086            Tag tag = getTag(Operation.class, null);
087            List<OperationChainContribution.Param> params = op.getParams();
088            if (params != null && !params.isEmpty()) {
089                Map<Object, Object> mapping = new HashMap<Object, Object>();
090                Map<Object, Object> subs = new LinkedHashMap<Object, Object>();
091                for (OperationChainContribution.Param param : params) {
092                    // handle java properties use case
093                    if (T_PROPERTIES.equals(param.getType())) {
094                        if (param.getMap() != null && !param.getMap().isEmpty()) {
095                            Properties props = new Properties(param.getMap());
096                            subs.put(param.getName(), props);
097                        } else {
098                            try {
099                                Properties props = new Properties(param.getValue());
100                                subs.put(param.getName(), props);
101                            } catch (IOException e) {
102                                subs.put(param.getName(), param.getValue());
103                            }
104                        }
105                    } else {
106                        subs.put(param.getName(), param.getValue());
107                    }
108                }
109                mapping.put(op.getId(), subs);
110                return representMapping(tag, mapping, null);
111            } else {
112                return YamlAutomationRepresenter.this.representData(op.getId());
113            }
114        }
115    }
116
117    public class ParamRepr implements Represent {
118        @Override
119        public Node representData(Object data) {
120            Param p = (Param) data;
121            Tag tag = getTag(Param.class, null);
122            Map<Object, Object> mapping = new HashMap<Object, Object>();
123            Map<Object, Object> subs = new LinkedHashMap<Object, Object>();
124            subs.put("type", p.getType());
125            if (p.getDescription() != null) {
126                subs.put("description", p.getDescription());
127            }
128            if (p.getValues() != null && p.getValues().length != 0) {
129                subs.put("values", p.getValues());
130            }
131            mapping.put(p.getName(), subs);
132            return representMapping(tag, mapping, null);
133        }
134    }
135
136}