Newer
Older
DesignCraft / src / main / java / models / objectOrientedTransfer / DataTransferContext.java
package models.objectOrientedTransfer;

import parser.ArrayValue;
import parser.JsonValue;
import parser.StringValue;
import parser.Value;
import parser.exceptions.ExpectedJsonValue;

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

/**
 * The reference context and properties of specific data transfer.
 *
 * @author Nitta
 *
 */
public class DataTransferContext {
    private List<Relation> relations;
    private Relation transferRelation;
    private ObjectNode dataType;
    private String dataName;
    private PushPullValue transferStyle;
    private Map<String, ObjectNode> objectNodeMap = new HashMap<>();

    public DataTransferContext(Value jsonValue) {
        setDataTransferContext(jsonValue);
    }

    public DataTransferContext(List<Relation> relations, Relation transferRelation, ObjectNode dataType, String dataName, PushPullValue transferStyle) {
        this.relations = relations;
        this.transferRelation = transferRelation;
        this.dataType = dataType;
        this.dataName = dataName;
        this.transferStyle = transferStyle;
    }

    public List<Relation> getRelations() {
        return relations;
    }

    public Relation getTransferRelation() {
        return transferRelation;
    }

    public boolean isFlat() {
        return transferRelation.isFlat();
    }

    public List<ReferenceEdge> getSrcResource() {
        return transferRelation.getSrcResource();
    }

    public List<ReferenceEdge> getDstResource() {
        return transferRelation.getDstResource();
    }

    public ObjectNode getSrcFirstResource() {
        return transferRelation.getSrcFirstResource();
    }

    public ObjectNode getDstFirstResource() {
        return transferRelation.getDstFirstResource();
    }


    public MultiplicityValue getTransferMultiplicity() {
        return transferRelation.getMultiplicity();
    }

    public ObjectNode getDataType() {
        return dataType;
    }

    public String getDataName() {
        return dataName;
    }

    public PushPullValue getTransferStyle() {
        return transferStyle;
    }

    private void setDataTransferContext(Value value) {
        if (value instanceof JsonValue) {
            for (StringValue keyValue : ((JsonValue) value).getJson().keySet()) {
                String key = keyValue.getStringValue();
                if (key.equals("relations")) {//この部分は動作未確認(おそらくまだ動かない)
                    relations = new ArrayList<>();
                    ArrayValue arrayValue = ((ArrayValue)((JsonValue) value).getValue(keyValue));
                    List<Value> relationValues = arrayValue.getValues();
                    for(Value relationValue:relationValues){
                        relations.add(getRelation(relationValue));
                    }
                } else if (key.equals("transfer")) {
                    transferRelation = getRelation(((JsonValue) value).getValue(keyValue));
                }
            }
        }
    }

    private Relation getRelation(Value value){
        if (value instanceof JsonValue) {
            MultiplicityValue multiplicityValue = null;
            List<ReferenceEdge> srcEdges = new ArrayList<>();
            List<ReferenceEdge> dstEdges = new ArrayList<>();
            ObjectNode src = null;
            ObjectNode dst = null;
            for (StringValue keyValue : ((JsonValue) value).getJson().keySet()) {
                String key = keyValue.getStringValue();
                if (key.equals("src")) {
                    src = setEdges((StringValue) ((JsonValue) value).getValue(keyValue), srcEdges);
                } else if (key.equals("dst")) {
                    dst = setEdges((StringValue) ((JsonValue) value).getValue(keyValue), dstEdges);
                } else if (key.equals("style")) {
                    setTransferStyle((StringValue) ((JsonValue) value).getValue(keyValue));
                } else if (key.equals("multiplicity")) {
                    StringValue multi = (StringValue) ((JsonValue) value).getValue(keyValue);
                    String multiplicity = multi.getStringValue();
                    if (multiplicity.equals("*:1")) {
                        multiplicityValue = MultiplicityValue.ManyToOne;
                    } else if (multiplicity.equals("1:1")) {
                        multiplicityValue = MultiplicityValue.OneToOne;
                    } else if (multiplicity.equals("*:*")) {
                        multiplicityValue = MultiplicityValue.ManyToMany;
                    } else if (multiplicity.equals("1:*")) {
                        multiplicityValue = MultiplicityValue.OneToMany;
                    }
                } else if (key.equals("data")) {
                    setTransferData(((JsonValue) value).getValue(keyValue));
                }
            }
            if (multiplicityValue == null) {
                throw new RuntimeException("multiplicityが存在していません");
            }
            if(src != null&&dst != null){//両方単独ObjectNode
                return new Relation(src,dst,multiplicityValue);
            }else if(src == null&&dst != null){//片方単独
                return new Relation(srcEdges,dst,multiplicityValue);
            }else if(src != null&&dst == null){//上と同じ
                return new Relation(src,dstEdges,multiplicityValue);
            }else{//両方複数
                return new Relation(srcEdges,dstEdges,multiplicityValue);
            }
        }
        throw new ExpectedJsonValue("Jsonではありません。");
    }

    private void setTransferStyle(StringValue stringValue){
        String style = stringValue.getStringValue();
        if (style.equals("PUSH")) {
            transferStyle = PushPullValue.PUSH;
        } else if (style.equals("PULL")) {
            transferStyle = PushPullValue.PULL;
        }
    }

    private void setTransferData(Value dataTransferValue){
        if (dataTransferValue instanceof JsonValue) {
            for (StringValue dataTransferValueKeyValue : ((JsonValue) dataTransferValue).getJson().keySet()) {
                String dataTransferValueKey = dataTransferValueKeyValue.getStringValue();
                if (dataTransferValueKey.equals("type")) {
                    String type = ((StringValue) ((JsonValue) dataTransferValue).getValue(dataTransferValueKeyValue)).getStringValue();
                    dataType = new ObjectNode(type);
                } else if (dataTransferValueKey.equals("name")) {
                    String name = ((StringValue) ((JsonValue) dataTransferValue).getValue(dataTransferValueKeyValue)).getStringValue();
                    dataName = name;
                }
            }
        } else {
            throw new ExpectedJsonValue("jsonのtransferのdataが足りていません");
        }
    }

    private ObjectNode setEdges(StringValue stringValue, List<ReferenceEdge> edges) {//objectNodeの場合はobjectNodeを返したい。
        String S = stringValue.getStringValue();
        int cur = 0;
        ArrayList<String> list = new ArrayList<>();
        while (cur < S.length()) {
            StringBuilder variable = new StringBuilder();
            while (cur < S.length() && S.charAt(cur) != '.') {
                variable.append(S.charAt(cur));
                cur++;
            }
            list.add(variable.toString());
            cur++;
        }
        if(list.size() == 1){//一つだけの場合はobjectNodeを返す
            String src = list.get(0);
            objectNodeMap.put(src, new ObjectNode(src));
            return objectNodeMap.get(src);
        }
        for (int i = 0; i < list.size() - 1; i++) {
            String src = list.get(i);
            String dst = list.get(i + 1);
            if (dst.charAt(0) == '{' && dst.charAt(dst.length() - 1) == '}') {//oneToMany
                dst = dst.substring(1, dst.length() - 1);
                if(!objectNodeMap.containsKey(dst)){
                    objectNodeMap.put(dst, new ObjectNode(dst));
                }
                if (src.charAt(0) == '{' && src.charAt(src.length() - 1) == '}') {
                    src = src.substring(1, src.length() - 1);
                    if (!objectNodeMap.containsKey(src)) {
                        objectNodeMap.put(src, new ObjectNode(src));
                    }
                } else {
                    if (!objectNodeMap.containsKey(src)) {
                        objectNodeMap.put(src, new ObjectNode(src));
                    }
                }
                edges.add(new ReferenceEdge(objectNodeMap.get(src), objectNodeMap.get(dst), convertTheFirstCharacterToLowerCase(dst), "String"));
            } else {//oneToOne
                if(!objectNodeMap.containsKey(dst)){
                    objectNodeMap.put(dst, new ObjectNode(dst));
                }
                if (src.charAt(0) == '{' && src.charAt(src.length() - 1) == '}') {
                    src = src.substring(1, src.length() - 1);
                    if (!objectNodeMap.containsKey(src)) {
                        objectNodeMap.put(src, new ObjectNode(src));
                    }
                } else {
                    if (!objectNodeMap.containsKey(src)) {
                        objectNodeMap.put(src, new ObjectNode(src));
                    }
                }
                edges.add(new ReferenceEdge(objectNodeMap.get(src), objectNodeMap.get(dst), convertTheFirstCharacterToLowerCase(dst)));
            }
        }
        return null;
    }

    private String convertTheFirstCharacterToLowerCase(String s){
        if(Character.isUpperCase(s.charAt(0))){
            s = s.substring(0,1).toLowerCase() + s.substring(1);
            return s;
        }else{
            return s;
        }
    }
}