001package org.dllearner.confparser.json;
002
003import org.dllearner.cli.ConfFileOption;
004import org.dllearner.confparser.AbstractConfParser;
005import org.dllearner.core.ComponentInitException;
006import org.jetbrains.annotations.NotNull;
007import org.json.simple.JSONObject;
008import org.json.simple.JSONValue;
009import org.json.simple.parser.JSONParser;
010import org.slf4j.Logger;
011import org.slf4j.LoggerFactory;
012
013import java.io.IOException;
014import java.io.InputStream;
015import java.io.InputStreamReader;
016import java.util.Collection;
017import java.util.Map;
018import java.util.Set;
019
020/**
021 * Convert Json Config to DL-Learner config
022 */
023public class ConfParserJson extends AbstractConfParser {
024        final static Logger logger = LoggerFactory.getLogger(ConfParserJson.class);
025        private InputStream inputStream;
026        private StringBuffer out;
027        private Map jsonMap;
028
029        public ConfParserJson(InputStream inputStream) {
030                this.inputStream = inputStream;
031                this.jsonMap = null;
032        }
033
034        public ConfParserJson(Map jsonMap) {
035                this.inputStream = null;
036                this.jsonMap = jsonMap;
037        }
038
039        private void resolveBeanRef(ConfFileOption o, Object value) throws ComponentInitException {
040                o.setPropertyType(value.getClass());
041                String jsonString = JSONValue.toJSONString(value);
042                if (value != null && !"null".equals(jsonString))
043                        o.setPropertyValue(value instanceof String ? (String) value : jsonString);
044
045                if (value instanceof String && ((String) value).startsWith("#")) {
046                        o.setBeanRef(true);
047                        o.setBeanReferenceCollection(false);
048                        o.setValueObject(((String) value).substring(1));
049                } else {
050                        Object vo = value;
051                        boolean refCollection = false;
052                        if (value instanceof Collection) {
053                                if (!((Collection) value).isEmpty()) {
054                                        Object first = ((Collection) value).iterator().next();
055                                        if (first instanceof String && ((String) first).startsWith("#")) {
056                                                o.setBeanReferenceCollection(true);
057                                                Collection v1new;
058                                                try {
059                                                        v1new = (Collection) value.getClass().newInstance();
060                                                } catch (InstantiationException e) {
061                                                        throw new ComponentInitException(e);
062                                                } catch (IllegalAccessException e) {
063                                                        throw new ComponentInitException(e);
064                                                }
065                                                for (Object o1 : (Collection) value) {
066                                                        if (!"#".equals(o1)) {
067                                                                if (o1 instanceof String && ((String) o1).startsWith("#"))
068                                                                        v1new.add(((String) o1).substring(1));
069                                                                else
070                                                                        v1new.add(o1);
071                                                        }
072                                                }
073                                                vo = v1new;
074                                                refCollection = true;
075                                        }
076                                }
077                        }
078                        o.setBeanRef(false);
079                        o.setBeanReferenceCollection(refCollection);
080                        o.setValueObject(vo);
081                }
082        }
083
084        public void init() throws ComponentInitException {
085                if (isInitialized()) return;
086
087                if (jsonMap == null) {
088                        jsonMap = parseJson();
089                }
090                convertMap();
091                postProcess();
092
093                this.initialized = true;
094        }
095
096        @NotNull
097        protected Map parseJson() throws ComponentInitException {
098                JSONObject ret = new JSONObject();
099                JSONParser parser = new JSONParser();
100
101                Object parse = null;
102                try {
103                        parse = parser.parse(new InputStreamReader(inputStream), new InsertionOrderedContainerFactory());
104                } catch (org.json.simple.parser.ParseException e) {
105                        throw new ComponentInitException(e.toString(), e);
106                } catch (IOException e) {
107                        throw new ComponentInitException(e);
108                }
109                logger.trace("parse was: " + parse.toString());
110                if (!(parse instanceof Map)) {
111                        throw new ComponentInitException("Not a JSON object: " + parse.getClass());
112                }
113                return (Map) parse;
114        }
115
116        public void convertMap() throws ComponentInitException {
117                for (Map.Entry e1 : (Set<Map.Entry>) jsonMap.entrySet()) {
118                        Object v1 = e1.getValue();
119                        final String k1 = (String) e1.getKey();
120                        if (v1 instanceof Map && ((Map) v1).containsKey("type")) {
121                                for (Map.Entry e2 : (Set<Map.Entry>) ((Map) v1).entrySet()) {
122                                        final String k2 = (String) e2.getKey();
123                                        if ("comment".equalsIgnoreCase(k2)) continue;
124                                        ConfFileOption o = new ConfFileOption();
125                                        o.setBeanName(k1);
126                                        o.setPropertyName(k2);
127                                        resolveBeanRef(o, e2.getValue());
128                                        addConfOption(o);
129                                }
130                        } else {
131                                ConfFileOption o = new ConfFileOption();
132                                o.setBeanName(k1);
133                                resolveBeanRef(o, v1);
134                                addConfOption(o);
135                        }
136                }
137        }
138}