package models.objectOrientedTransfer;
import parser.JsonValue;
import parser.StringValue;
import parser.Value;
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<>();
continue;
} else if (key.equals("transfer")) {
setTransfer(((JsonValue) value).getValue(keyValue));
}
}
}
}
private void setTransfer(Value value) {
if (value instanceof JsonValue) {
MultiplicityValue multiplicityValue = null;
List<ReferenceEdge> srcEdges = new ArrayList<>();
List<ReferenceEdge> dstEdges = new ArrayList<>();
for (StringValue keyValue : ((JsonValue) value).getJson().keySet()) {
String key = keyValue.getStringValue();
if (key.equals("src")) {
setEdges((StringValue) ((JsonValue) value).getValue(keyValue), srcEdges);
} else if (key.equals("dst")) {
setEdges((StringValue) ((JsonValue) value).getValue(keyValue), dstEdges);
} else if (key.equals("style")) {
StringValue styleValue = (StringValue) ((JsonValue) value).getValue(keyValue);
String style = styleValue.getStringValue();
if (style.equals("PUSH")) {
transferStyle = PushPullValue.PUSH;
} else if (style.equals("PULL")) {
transferStyle = PushPullValue.PULL;
}
System.out.println(style);
} 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;
}
System.out.println(multiplicity);
} else if (key.equals("data")) {
Value dataTransferValue = ((JsonValue) value).getValue(keyValue);
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 RuntimeException("jsonのtransferのdataが足りていません");
}
}
}
if (multiplicityValue == null) {
throw new RuntimeException("multiplicityが存在していません");
}
transferRelation = new Relation(srcEdges, dstEdges, multiplicityValue);
}
}
private void setEdges(StringValue stringValue, List<ReferenceEdge> edges) {
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++;
}
//この下エラー吐いてます
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);
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), dst, "String"));
} else {//oneToOne
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), dst));
}
}
}
}