view src/main/java/jp/ac/u_ryukyu/ie/cr/jungle/commandline/commandline.java @ 308:201cc75a9984

change Red Black Tree Edit Path Extends
author tatsuki
date Thu, 26 Jan 2017 15:23:25 +0900
parents 0767620e6f5f
children 2a0cb1f0ba4e
line wrap: on
line source

package jp.ac.u_ryukyu.ie.cr.jungle.commandline;

import jp.ac.u_ryukyu.ie.cr.jungle.DefaultJungle;
import jp.ac.u_ryukyu.ie.cr.jungle.Jungle;
import jp.ac.u_ryukyu.ie.cr.jungle.query.traverser.InterfaceTraverser;
import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.DefaultNodePath;
import jp.ac.u_ryukyu.ie.cr.jungle.store.nodepath.NodePath;
import jp.ac.u_ryukyu.ie.cr.jungle.store.omnigraffle.OmniGraffleCreater;
import jp.ac.u_ryukyu.ie.cr.jungle.transaction.editor.jungleTreeEditor.JungleTreeEditor;
import jp.ac.u_ryukyu.ie.cr.jungle.transaction.node.TreeNode;
import jp.ac.u_ryukyu.ie.cr.jungle.tree.JungleTree;
import jp.ac.u_ryukyu.ie.cr.jungle.util.DefaultEither;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Either;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.DefaultError;
import jp.ac.u_ryukyu.ie.cr.jungle.util.Error.Error;
import jp.ac.u_ryukyu.ie.cr.jungle.xml.reader.XmlReader;

import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.TransformerException;
import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.URISyntaxException;
import java.nio.ByteBuffer;
import java.util.Iterator;
import java.util.LinkedList;

/*
 * コマンドラインの簡単な使い方
 * エラー処理とかはまだ書いてない
 * 本当にプロトタイプ
 *
 * 
 * 木の一覧
 * trees
 *
 * データのimport
 * treeName.import(path/to/xml)
 *
 * データのexport
 * treeName.export()
 * treeのデータをomnigraffle形式で出力する
 *
 *
 * データのfind
 * treeName.find()
 * で全てのデータを表示
 *
 * treeName.find(条件)
 * で条件に一致するNodeの取得
 * 例 treeName.find(name = kanagawa)
 *
 * treeName.find(条件, {表示するkey})
 * 条件に一致するNodeの表示するkeyを表示する
 *
 * treeName.find(, {表示するkey})
 * でも OK
 * treeName.find(検索するkey 例 id) 絞込はまだ treeNameは:revisionで過去のTreeにアクセス可能 find(条件,{表示するkey})
 *
 * Nodeの追加
 * treeName.insert(<path>,key:value,key:value………)
 *
 * attribute等のupdate
 * treeName.insertAttribute(path,key:value, ………) treeName path <Path> keys key values attribute
 *
 */

public class commandline {
    Jungle jungle = new DefaultJungle(null, "hoge");

    public void start() throws IOException, InterruptedException {
        System.out.println("jungle 対話モード");
        while (true) {
            try {
                System.out.println("入力受付中");

                InputStreamReader isr = new InputStreamReader(System.in);
                BufferedReader br = new BufferedReader(isr);
                String str = br.readLine();
                switch (str) {
                    case "exit":
                        System.out.println("see you");
                        System.exit(0);
                        break;
                    case "trees":
                        showTrees();
                    default:
                        parse(str);

                }
            } catch (Exception e) {
                e.printStackTrace();
                System.out.println("不正な入力です");
            }
        }
    }

    private void showTrees() {
        System.out.println("---------------------------------------------------------------------");
        Iterator<String> treeNames = jungle.getTreeNames();
        for (; treeNames.hasNext(); ) {
            System.out.println(treeNames.next());
        }
        System.out.println("---------------------------------------------------------------------");
    }

    private void parse(String sql) throws ParserConfigurationException, TransformerException, IOException, URISyntaxException {
        String[] split = sql.replace(" ", "").split("\\.");
        Iterator<String> iterator = new Iterator<String>() {
            private int count = 0;

            @Override
            public boolean hasNext() {
                return count < split.length;
            }

            @Override
            public String next() {
                String tmp = split[count];
                count++;
                return tmp;
            }
        };

        String treeName = "";
        if (iterator.hasNext())
            treeName = iterator.next();

        String[] cmd = new String[2];
        if (iterator.hasNext()) {
            String str = iterator.next();
            cmd = str.split("\\(");
        }

        if (cmd[1] != null) {
            switch (cmd[0]) {
                case "find":
                    String condition = cmd[1].replace(")", "");  // )を取り除く
                    find(treeName, condition, iterator);
                    break;
                case "insert":
                    String value = cmd[1].replace(")", "");  // )を取り除く
                    insert(treeName, value, iterator);
                    break;
                case "insertAttribute":
                    value = cmd[1].replace(")", "");  // )を取り除く
                    update(treeName, value, iterator);
                    break;
                case "import"://attribute等のupdate treeName path <Path> keys key values attribute
                    String url = cmd[1].replace(")", ""); // )を取り除く
                    dataImport(treeName, url); //xmlをimportする treename.import(url)
                    break;
                case "export"://木をOmniGraffle形式にExportする
                    dataExport(treeName);
                    break;
            }
        }
    }

    private void dataExport(String treeName) throws URISyntaxException, ParserConfigurationException, TransformerException, IOException {
        JungleTree tree = jungle.getTreeByName(treeName);
        OmniGraffleCreater omnigraffleCreater = new OmniGraffleCreater(treeName,tree);
        omnigraffleCreater.createJungleTreeClassDiagram();
    }

    private void dataImport(String treeName, String url) {
        if (treeName.equals("") || url.equals("")) {
            System.out.println("faild");
            return;
        }
        JungleTree tree = jungle.createNewTree(treeName);
        if (tree == null)
            tree = jungle.getTreeByName(treeName);
        new XmlReader().start(url + ".xml", tree);
    }

    private void update(String treeName, String args, Iterator<String> iterator) {
        {
            String[] split = args.split(">");//,で分割するとpathがおかしくなるので>で分割することでpathとkey:valueの組み合わせに分ける
            if (split.length < 2) {
                return;
            }
            DefaultNodePath path = new DefaultNodePath();
            String pathStr = "";
            pathStr = split[0]; // pathを取得する
            pathStr = pathStr.substring(1, pathStr.length()); // <を取り取り除く
            String[] nums = pathStr.split(",");
            for (String num : nums) {
                if (num.equals("-1"))
                    continue;
                path = path.add(new Integer(num));
            }

            split = split[1].split(",");//ここで後ろのkey:valueの組み合わせを,で分割する
            LinkedList<String> values = new LinkedList<>();
            LinkedList<String> keys = new LinkedList<>();
            for (String s : split) {
                String[] pair = s.split(":");
                if (pair.length != 2)
                    continue;
                String k = pair[0];
                String v = pair[1];
                keys.add(k);//表示するkeyを表示
                values.add(v);
            }


            JungleTree tree = jungle.getTreeByName(treeName);
            if (tree == null)
                tree = jungle.createNewTree(treeName);
            JungleTreeEditor editor = tree.getJungleTreeEditor();
            Iterator<String> keyIterator = keys.iterator();
            Iterator<String> valueIterator = values.iterator();
            Either<Error, JungleTreeEditor> either = DefaultEither.newA(new DefaultError());
            while (keyIterator.hasNext()) {//値の追加
                String key = keyIterator.next();
                String value = valueIterator.next();
                either = editor.putAttribute(path, key, ByteBuffer.wrap(value.getBytes()));
                if (either.isA())//aattributeの追加に失敗したらその場でupdate終了
                    return;
                editor = either.b();
            }
            editor.success();
            if (either.isA())//commitに失敗したらその場でinsert終了
                System.out.println("faild");
        }
    }

    private void insert(String treeName, String args, Iterator<String> iterator) {
        String[] split = args.split(">");//,で分割するとpathがおかしくなるので>で分割することでpathとkey:valueの組み合わせに分ける
        if (split.length < 2) {
            return;
        }
        DefaultNodePath path = new DefaultNodePath();
        String pathStr = "";
        pathStr = split[0]; // pathを取得する
        pathStr = pathStr.substring(1, pathStr.length()); // <を取り取り除く
        String[] nums = pathStr.split(",");
        for (String num : nums) {
            if (num.equals("-1"))
                continue;
            path = path.add(new Integer(num));
        }

        split = split[1].split(",");//ここで後ろのkey:valueの組み合わせを,で分割する
        LinkedList<String> values = new LinkedList<>();
        LinkedList<String> keys = new LinkedList<>();
        for (String s : split) {
            String[] pair = s.split(":");
            if (pair.length != 2)
                continue;
            String k = pair[0];
            String v = pair[1];
            keys.add(k);//表示するkeyを表示
            values.add(v);
        }

        JungleTree tree = jungle.getTreeByName(treeName);
        if (tree == null)
            tree = jungle.createNewTree(treeName);
        JungleTreeEditor editor = tree.getJungleTreeEditor();
        Iterator<String> keyIterator = keys.iterator();
        Iterator<String> valueIterator = values.iterator();
        NodePath parentPath = path.last().right(); // Nodeの追加
        int num = path.last().left();
        Either<Error, JungleTreeEditor> either = editor.addNewChildAt(parentPath, num);
        if (either.isA()) {
            System.out.println("faild");// Nodeの追加に失敗したらその場でinsert終了
            return;
        }
        editor = either.b();
        while (keyIterator.hasNext()) {//値の追加
            String key = keyIterator.next();
            String value = valueIterator.next();
            either = editor.putAttribute(path, key, ByteBuffer.wrap(value.getBytes()));
            if (either.isA())//Nodeの追加に失敗したらその場でinsert終了
                return;
            editor = either.b();
        }
        editor.success();
        if (either.isA())//Nodeの追加に失敗したらその場でinsert終了
            System.out.println("faild");
    }


    private void find(String treeName, String args, Iterator<String> iterator) { //conditionには条件が入るが今はkeyのみしか入らない。
        //取得するkeyの取得
        String[] conditionAndKeys = args.split("\\{");
        String[] conditions = conditionAndKeys[0].split(",");

        String[] keys;

        if (conditionAndKeys.length >= 2)
            keys = conditionAndKeys[1].replace("}", "").split(",");
        else {
            keys = new String[1];
            keys[0] = "";
        }
        String[] split = treeName.split(":"); // TreeName:idで表記されているのでTreename と Idに分割する
        treeName = split[0];//TreeNameの取得
        JungleTree tree = jungle.getTreeByName(treeName);
        if (tree == null) {
            System.out.println("tree no found");
            return;
        }

        if (split.length == 2) {
            Either<Error, JungleTree> either = jungle.getTreeByName(treeName).getOldTree(new Long(split[1]));
            if (either.isA()) {
                tree = jungle.getTreeByName(treeName);
            } else {
                tree = either.b();
            }
        }

        InterfaceTraverser traverser = tree.getTraverser(true);
        Iterator<TreeNode> nodeIterator = traverser.find((TreeNode node) -> { //この場合条件がないので探索する木のNodeを全て取得する
            for (String condition : conditions) {
                String[] keyConditionPair;

                if (condition.contains(">=")) {
                    keyConditionPair = condition.split(">=");
                    String key = keyConditionPair[0];
                    String valueString = node.getAttributes().getString(key);
                    if (valueString == null)
                        return false;
                    int value = new Integer(valueString);
                    int require = new Integer(keyConditionPair[1]);
                    if (value >= require)
                        continue;
                    return false;
                }

                if (condition.contains("<=")) {
                    keyConditionPair = condition.split("<=");
                    String key = keyConditionPair[0];
                    String valueString = node.getAttributes().getString(key);
                    if (valueString == null)
                        return false;
                    int value = new Integer(valueString);
                    int require = new Integer(keyConditionPair[1]);
                    if (value <= require)
                        continue;
                    return false;
                }

                if (condition.contains("<")) {
                    keyConditionPair = condition.split("<");
                    String key = keyConditionPair[0];
                    String valueString = node.getAttributes().getString(key);
                    if (valueString == null)
                        return false;
                    int value = new Integer(valueString);
                    int require = new Integer(keyConditionPair[1]);
                    if (value < require)
                        continue;
                    return false;
                }


                if (condition.contains(">")) {
                    keyConditionPair = condition.split(">");
                    String key = keyConditionPair[0];
                    String valueString = node.getAttributes().getString(key);
                    if (valueString == null)
                        return false;
                    int value = new Integer(valueString);
                    int require = new Integer(keyConditionPair[1]);
                    if (value > require)
                        continue;
                    return false;
                }

                keyConditionPair = condition.split("=");
                if (keyConditionPair.length == 1)
                    continue;
                String value = node.getAttributes().getString(keyConditionPair[0]);
                String requireValue = keyConditionPair[1];
                if (value == null)
                    return false;
                if (!value.equals(requireValue))
                    return false;
            }
            return true;
        });

        while (nodeIterator.hasNext()) {
            TreeNode node = nodeIterator.next();
            System.out.println("---------------------------------------------------------------------");
            System.out.println("path = " + tree.getNodePath(node));
            Iterator<String> nodeKeys;
            if (keys[0].equals(""))
                nodeKeys = node.getAttributes().getKeys();
            else {
                nodeKeys = new Iterator<String>() {
                    private int count = 0;

                    @Override
                    public boolean hasNext() {
                        return count < keys.length;
                    }

                    @Override
                    public String next() {
                        String tmp = keys[count];
                        count++;
                        return tmp;
                    }
                };
                ;
            }
            while (nodeKeys.hasNext()) {
                String key = nodeKeys.next();
                String value = node.getAttributes().getString(key);
                if (value != null)
                    System.out.println(key + "=" + value + ",");
            }
        }


    }
}