All Downloads are FREE. Search and download functionalities are using the official Maven repository.

reflex.AbstractReflexDataHandler Maven / Gradle / Ivy

There is a newer version: 3.0.4
Show newest version
/**
 * The MIT License (MIT)
 *
 * Copyright (c) 2011-2016 Incapture Technologies LLC
 *
 * Permission is hereby granted, free of charge, to any person obtaining a copy
 * of this software and associated documentation files (the "Software"), to deal
 * in the Software without restriction, including without limitation the rights
 * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
 * copies of the Software, and to permit persons to whom the Software is
 * furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice shall be included in all
 * copies or substantial portions of the Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
 * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
 * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
 * SOFTWARE.
 */
package reflex;

import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;

import org.apache.log4j.Logger;

import rapture.common.BlobContainer;
import rapture.common.RaptureURI;
import rapture.common.SeriesPoint;
import rapture.common.api.ScriptingApi;
import rapture.common.impl.jackson.JacksonUtil;
import reflex.node.KernelExecutor;
import reflex.util.MapConverter;
import reflex.value.ReflexValue;
import reflex.value.internal.ReflexNullValue;

import com.google.common.net.MediaType;

public abstract class AbstractReflexDataHandler implements IReflexDataHandler {

    private static Logger log = Logger.getLogger(AbstractReflexDataHandler.class);
    protected ScriptingApi api;
    protected ScriptingApi originalApi;

    public static final String CSV = MediaType.CSV_UTF_8.toString().split(";")[0].trim();

    public AbstractReflexDataHandler(ScriptingApi scriptClient) {
        this.api = scriptClient;
        this.originalApi = scriptClient;
    }

    public ReflexValue pullData(RaptureURI uri) {
        switch (uri.getScheme()) {
            case DOCUMENT:
                String strContent = api.getDoc().getDoc(uri.toString());
                return (strContent == null)
                        ? new ReflexNullValue()
                        : new ReflexValue(MapConverter.convertMap(JacksonUtil.getMapFromJson(strContent)));

            case SERIES:
                List series = api.getSeries().getPoints(uri.toString());
                ReflexValue retSeries = new ReflexValue(series);
                return retSeries;

            case BLOB:
                BlobContainer blobContainer = api.getBlob().getBlob(uri.toString());
                if (blobContainer == null) return null;
                String input = new String(blobContainer.getContent());
                if (input.isEmpty()) return new ReflexNullValue();

                String contentType = blobContainer.getHeaders().get("Content-Type");
                if (contentType != null) {
                    if (contentType.startsWith(CSV)) {
                        List linesArray = new ArrayList();
                        String[] rows = input.split("\n");
                        for (String row : rows) {
                            List lineArray = new ArrayList();
                            for (String value : row.split(",")) {
                                lineArray.add(new ReflexValue(value));
                            }
                            linesArray.add(new ReflexValue(lineArray));
                        }
                        return new ReflexValue(linesArray);
                    }
                }
                return new ReflexValue(input);

            default:
                throw new ReflexException(-1, "Pull from " + uri + " not supported yet");
        }

    }

    @Override
    public void pushData(RaptureURI uri, ReflexValue data, MediaType metadata) {
        String uriStr = uri.toString(); // sigh
        switch (uri.getScheme()) {

            case SERIES:
                List series = data.asList();
                if (series == null) throw new ReflexException(-1, "Cannot write " + data.getTypeAsString() + " to " + uri);

                if (series.size() == 2) {
                    List l0 = series.get(0).asList();
                    List l1 = series.get(1).asList();
                    if ((l0 == null) || (l1 == null) || (l0.size() != l1.size())) {
                        throw new ReflexException(-1, "Cannot write " + data.getTypeAsString() + " to " + uri + " - illegal format");
                    }
                    for (int i = 0; i < l0.size(); i++) {
                        ReflexValue val = l1.get(1);
                        if (val.isString()) api.getSeries().addStringToSeries(uriStr, l0.get(i).toString(), val.toString());
                        else if (val.isNumber()) api.getSeries().addDoubleToSeries(uriStr, l0.get(i).toString(), val.asDouble());
                    }
                } else {
                    ReflexValue first = series.get(0);
                    if (first.isComplex()) {
                        Object val = first.getValue();
                        if (val instanceof SeriesPoint) {
                            for (ReflexValue rv : series) {
                                SeriesPoint sp = (SeriesPoint) rv.getValue();
                                api.getSeries().addStringToSeries(uriStr, sp.getColumn(), sp.getValue());
                            }
                        } else {
                            throw new ReflexException(-1, "Cannot add " + val.getClass().getSimpleName() + " to series");
                        }
                    } else {
                        List firstEntry = first.asList();
                        if (firstEntry == null) {
                            throw new ReflexException(-1, "Expected a list for " + series.get(0));
                        }
                        int lengthExpect = firstEntry.size();
                        if (lengthExpect < 2) {
                            throw new ReflexException(-1, "Expected at least two values " + series.get(0));
                        }
                        for (Object obj : series) {
                            if (!(obj instanceof ReflexValue)) obj = new ReflexValue(obj);
                            ReflexValue rv = (ReflexValue) obj;
                            List entry = rv.asList();
                            if (entry == null) {
                                log.error("Ignoring illegal entry " + rv + " in list");
                                continue;
                            }
                            if (entry.size() != lengthExpect) {
                                log.error("Ignoring " + entry + " as it has size " + entry.size() + " - expected " + lengthExpect);
                                continue;
                            }
                            String newUri = uriStr;
                            for (int i = 0; i < lengthExpect - 2; i++) {
                                newUri = newUri + "/" + entry.get(i).toString();
                            }
                            ReflexValue val = entry.get(lengthExpect - 1);
                            if (val.isString()) api.getSeries().addStringToSeries(newUri, entry.get(lengthExpect - 2).toString(), val.toString());
                            else if (val.isNumber()) api.getSeries().addDoubleToSeries(newUri, entry.get(lengthExpect - 2).toString(), val.asDouble());
                        }
                    }
                }
                break;

            case DOCUMENT:
                Map map;

                if (data.isMap()) {
                    map = KernelExecutor.convert(data.asMap());
                } else if (data.isList()) {
                    List list = data.asList();
                    map = rvListToMap(list);
                } else throw new ReflexException(-1, "Cannot write " + data.getTypeAsString() + " to " + uri);

                api.getDoc().putDoc(uriStr, JacksonUtil.prettyfy(JacksonUtil.jsonFromObject(map)));
                break;

            case BLOB:
                byte[] bytes = data.asByteArray();
                if (bytes == null) throw new ReflexException(-1, "Cannot write " + data.getTypeAsString() + " to " + uri);
                api.getBlob().putBlob(uriStr, bytes, metadata.toString());
                break;

            default:
                throw new ReflexException(-1, "Cannot write " + data.getTypeAsString() + " to " + uri);
        }
    }

    @SuppressWarnings("unchecked")
    private static void listToMap(Map map, List list) {
        int size = list.size();
        if (size == 0) return;
        if (size == 1) {
            map.put("value", list.get(0).getValue());
        } else if (size == 2) {
            map.put(list.get(0).toString(), list.get(1).getValue());
        } else {
            String key = list.get(0).toString();
            Map childMap;
            Object child = map.get(key);
            if (child != null) {
                if (!(child instanceof Map)) {
                    throw new ReflexException(-1, "Internal error: " + child.getClass().getSimpleName() + " is not a Map");
                } else {
                    childMap = (Map) child;
                }
            } else {
                childMap = new HashMap<>();
                map.put(key, childMap);
            }
            listToMap(childMap, list.subList(1, size));
        }
    }

    public static Map rvListToMap(List list) {
        Map ret = new HashMap<>();
        for (ReflexValue rvElem : list) {
            if (rvElem.isList()) {
                listToMap(ret, rvElem.asList());
            }
        }
        return ret;
    }

    public static List mapToRVList(Map map) {
        List list = new ArrayList<>();
        for (Entry entry : map.entrySet()) {
            if (entry.getValue() instanceof Map) {
                @SuppressWarnings("unchecked")
                List sublist = mapToRVList((Map) entry.getValue());
                for (ReflexValue val : sublist) {
                    val.asList().add(0, new ReflexValue(entry.getKey()));
                }
                list.addAll(sublist);
            } else {
                List sublist = new ArrayList<>();
                sublist.add(new ReflexValue(entry.getKey()));
                sublist.add(new ReflexValue(entry.getValue()));
                list.add(new ReflexValue(sublist));
            }
        }
        return list;
    }

}




© 2015 - 2025 Weber Informatics LLC | Privacy Policy