ModelData.java [src/csip] Revision: 71821307bfe742c00c6dc582c171224a9ac59935  Date: Fri Apr 21 11:46:19 MDT 2017
/*
 * $Id$
 *
 * This file is part of the Cloud Services Integration Platform (CSIP),
 * a Model-as-a-Service framework, API and application suite.
 *
 * 2012-2017, Olaf David and others, OMSLab, Colorado State University.
 *
 * OMSLab licenses this file to you under the MIT license.
 * See the LICENSE file in the project root for more information.
 */
package csip;

import static csip.ModelDataService.KEY_VALUE;
import static csip.ModelDataService.KEY_NAME;
import csip.utils.JSONUtils;
import java.util.HashMap;
import java.util.LinkedHashMap;
import java.util.Map;
import java.util.TreeMap;
import java.util.logging.Level;
import java.util.logging.Logger;
import org.codehaus.jettison.json.JSONArray;
import org.codehaus.jettison.json.JSONException;
import org.codehaus.jettison.json.JSONObject;

/**
 *
 * @author od
 */
public class ModelData {

    private Map<String, Object> data;
    private String name = "?";

    public static final int INSERTION_ORDER = 1;
    public static final int ALPHABETICAL_ORDER = 2;


    public ModelData() {
        this(INSERTION_ORDER);
    }


    public ModelData(int order) {
        data = (order == ALPHABETICAL_ORDER)
                ? new TreeMap<String, Object>()
                : new LinkedHashMap<String, Object>();
    }


    ModelData(String name, JSONArray param) {
        this(INSERTION_ORDER);
        this.name = name;
        try {
            data = fromJSON(param);
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public void put(String name, ModelData md) {
        if (this == md) {
            throw new IllegalArgumentException("do not add '" + name + "' to itself.");
        }
        md.setName(name);
        data.put(name, md);
    }


    public void put(String name, String value) {
        try {
            data.put(name, JSONUtils.data(name, value));
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


///////// Integer
    public void put(String name, int value) {
        try {
            data.put(name, JSONUtils.data(name, value));
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public void put(String name, int value, String descr) {
        try {
            data.put(name, JSONUtils.data(name, value, descr));
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public void put(String name, int[] value) {
        try {
            data.put(name, JSONUtils.data(name, JSONUtils.toArray(value)));
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public int getInt(String name) throws ServiceException {
        try {
            return getJSONObject(name).getInt(KEY_VALUE);
        } catch (JSONException | IllegalArgumentException ex) {
            throw new ServiceException("'" + name + "': " + ex.getMessage());
        }
    }


    public int getInt(String name, int def) {
        try {
            return getJSONObject(name).getInt(KEY_VALUE);
        } catch (JSONException | IllegalArgumentException ex) {
            return def;
        }
    }


    protected int[] getIntArrayParam(String name) throws ServiceException {
        return getIntArrayParam(name, null);
    }


    protected int[] getIntArrayParam(String name, int[] def) throws ServiceException {
        try {
            JSONArray a = getJSONObject(name).getJSONArray(KEY_VALUE);
            return JSONUtils.toIntArray(a);
        } catch (JSONException ex) {
            return def;
        }
    }


////double
    public void put(String name, double value) {
        try {
            data.put(name, JSONUtils.data(name, value));
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public void put(String name, double value, String descr) {
        try {
            data.put(name, JSONUtils.data(name, value, descr));
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public void put(String name, double[] value) {
        try {
            data.put(name, JSONUtils.data(name, JSONUtils.toArray(value)));
        } catch (JSONException ex) {
            Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
        }
    }


    public double getDouble(String name) throws ServiceException {
        try {
            return getJSONObject(name).getDouble(KEY_VALUE);
        } catch (JSONException | IllegalArgumentException ex) {
            throw new ServiceException("'" + name + "': " + ex.getMessage());
        }
    }


    public double getDouble(String name, double def) {
        try {
            return getJSONObject(name).getDouble(KEY_VALUE);
        } catch (JSONException | IllegalArgumentException ex) {
            return def;
        }
    }


    protected double[] getDoubleArrayParam(String name) throws ServiceException {
        return getDoubleArrayParam(name, null);
    }


    protected double[] getDoubleArrayParam(String name, double[] def) throws ServiceException {
        try {
            JSONArray a = getJSONObject(name).getJSONArray(KEY_VALUE);
            return JSONUtils.toDoubleArray(a);
        } catch (JSONException ex) {
            return def;
        }
    }


    public ModelData getData(String name) {
        Object o = data.get(name);
        if (o != null && o instanceof ModelData) {
            return (ModelData) o;
        }
        return null;
    }


    public JSONObject getJSONObject(String name) {
        Object o = data.get(name);
        if (o != null && !(o instanceof ModelData)) {
            return (JSONObject) o;
        }
        throw new IllegalArgumentException("Data not not found in '" + this.name + "': " + name);
    }


    ///////////////////// private helper methods
    private void setName(String name) {
        this.name = name;
    }


    private void setData(Map<String, Object> data) {
        this.data = data;
    }


    static Map<String, Object> fromJSON(JSONArray data) throws JSONException {
        Map<String, Object> p = new HashMap<>();
        for (int i = 0; i < data.length(); i++) {
            JSONObject o = data.getJSONObject(i);
            String name = o.getString(KEY_NAME);
            Object value = o.get(KEY_VALUE);
            if (value instanceof JSONArray) {
                Map<String, Object> vm = fromJSON((JSONArray) value);
                ModelData d = new ModelData();
                d.setData(vm);
                p.put(name, d);
            } else {
                p.put(name, o);
            }
        }
        return p;
    }


    JSONArray asJSON() {
        JSONArray a = new JSONArray();
        for (Object o : data.values()) {
            if (o instanceof JSONObject) {
                a.put((JSONObject) o);
            } else if (o instanceof ModelData) {
                ModelData o_ = (ModelData) o;
                JSONObject param = new JSONObject();
                try {
                    param.put(KEY_NAME, o_.name);
                    param.put(KEY_VALUE, o_.asJSON());
                } catch (JSONException ex) {
                    Logger.getLogger(ModelData.class.getName()).log(Level.SEVERE, null, ex);
                }
                a.put(param);
            }
        }
        return a;
    }


    @Override
    public String toString() {
        try {
            return asJSON().toString(2);
        } catch (JSONException ex) {
            return asJSON().toString();
        }
    }


    public static void main(String[] args) throws Exception {
        ModelData d = new ModelData();
        d.put("zdk_days", 123);
        d.put("dk_days1", "true");
        d.put("xdk_days", 123);

        ModelData d1 = new ModelData();
        d.put("fam", d1);

        d1.put("od", "999");
        d1.put("ad", "david1");

        System.out.println(d);

        JSONArray a = d.asJSON();

        ModelData d3 = new ModelData("param", a);

//        System.out.println(d3.getInt("dk_days"));
        ModelData d4 = d3.getData("fam");
        d4.put("od", 20);

//        System.out.println(d3);
//        System.out.println(d);
    }
}