org.loklak.harvester.JsonFieldConverter.java Source code

Java tutorial

Introduction

Here is the source code for org.loklak.harvester.JsonFieldConverter.java

Source

/**
 * JsonFieldConverter
 * Copyright 09.04.2015 by Dang Hai An, @zyzo
 * <p/>
 * This library is free software; you can redistribute it and/or
 * modify it under the terms of the GNU Lesser General Public
 * License as published by the Free Software Foundation; either
 * version 2.1 of the License, or (at your option) any later version.
 * <p/>
 * This library is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 * Lesser General Public License for more details.
 * <p/>
 * You should have received a copy of the GNU Lesser General Public License
 * along with this program in the file lgpl21.txt
 * If not, see <http://www.gnu.org/licenses/>.
 */

package org.loklak.harvester;

import org.json.JSONArray;
import org.json.JSONObject;
import org.loklak.data.DAO;

import java.io.IOException;
import java.util.*;
import java.util.regex.Pattern;

public class JsonFieldConverter {

    public enum JsonConversionSchemaEnum {
        FOSSASIA("fossasia.json"), OPENWIFIMAP("openwifimap.json"), NODELIST_NODE(
                "nodelist-node.json"), FREIFUNK_NODE("freifunk-node.json"), NETMON_NODE("netmon-node.json"),;
        private String filename;

        JsonConversionSchemaEnum(String filename) {
            this.filename = filename;
        }

        public String getFilename() {
            return filename;
        }
    }

    private Map<String, List<String>> conversionRules;

    @SuppressWarnings("unchecked")
    public JsonFieldConverter(JsonConversionSchemaEnum conversionSchema) throws IOException {
        final JSONObject convSchema = DAO.getConversionSchema(conversionSchema.getFilename());
        List<List<?>> convRules = (List<List<?>>) convSchema.get("rules");
        this.conversionRules = new HashMap<>();
        for (List<?> rule : convRules) {
            List<String> toInsert = new ArrayList<>();
            this.conversionRules.put((String) rule.get(0), toInsert);

            // the 2nd rule can be either a string
            if (rule.get(1) instanceof String) {
                toInsert.add((String) rule.get(1));
            } else {
                // or an array
                for (String afterField : (List<String>) rule.get(1)) {
                    toInsert.add(afterField);
                }
            }
        }
    }

    public JSONArray convert(JSONArray initialJson) throws IOException {
        JSONArray result = new JSONArray();
        for (Object o : initialJson) {
            result.put(this.convert((JSONObject) o));
        }
        return result;
    }

    public JSONObject convert(JSONObject initialJson) throws IOException {
        Iterator<Map.Entry<String, List<String>>> it = this.conversionRules.entrySet().iterator();
        while (it.hasNext()) {
            Map.Entry<String, List<String>> entry = (Map.Entry<String, List<String>>) it.next();
            String key = entry.getKey();
            Object value = getFieldValue(initialJson, key);

            if (value == null) {
                continue;
            } // field not found

            for (String newKey : entry.getValue()) {
                putToField(initialJson, newKey, value);
            }
        }
        return initialJson;
    }

    private static Object getFieldValue(JSONObject object, String key) {
        if (key.contains(".")) {
            String[] deepFields = key.split(Pattern.quote("."));
            JSONObject currentLevel = object;
            for (int lvl = 0; lvl < deepFields.length; lvl++) {
                if (lvl == deepFields.length - 1) {
                    return currentLevel.get(deepFields[lvl]);
                } else {
                    if (currentLevel.get(deepFields[lvl]) == null) {
                        return null;
                    }
                    currentLevel = (JSONObject) currentLevel.get(deepFields[lvl]);
                }
            }
        } else {
            return object.get(key);
        }
        // unreachable code
        return null;
    }

    private static void putToField(JSONObject object, String key, Object value) {
        if (key.contains(".")) {
            String[] deepFields = key.split(Pattern.quote("."));
            JSONObject currentLevel = object;
            for (int lvl = 0; lvl < deepFields.length; lvl++) {
                if (lvl == deepFields.length - 1) {
                    currentLevel.put(deepFields[lvl], value);
                } else {
                    if (currentLevel.get(deepFields[lvl]) == null) {
                        currentLevel.put(deepFields[lvl], new HashMap<>());
                    }
                    currentLevel = (JSONObject) currentLevel.get(deepFields[lvl]);
                }
            }
        } else {
            object.put(key, value);
        }
    }
}