001package gudusoft.gsqlparser.dlineage.dataflow.model.xml;
002
003import java.util.ArrayList;
004import java.util.Comparator;
005import java.util.HashSet;
006import java.util.List;
007import java.util.Objects;
008import java.util.Set;
009
010import javax.xml.bind.annotation.XmlAttribute;
011import javax.xml.bind.annotation.XmlElement;
012import javax.xml.bind.annotation.XmlType;
013
014import gudusoft.gsqlparser.util.SQLUtil;
015
016@XmlType(propOrder = {"id", "type", "function", "effectType", "partition", "clause", "joinType", "target", "caller", "sources", "callees", "processId", "processType", "procedureId", "sqlHash", "sqlComment", "condition", "timestampMin", "timestampMax", "callStmt", "callCoordinate"})
017public class relationship implements Cloneable {
018
019    private String id;
020
021    private String type;
022
023    private String function;
024
025    private String effectType;
026
027    private String clause;
028
029    private String joinType;
030
031    private targetColumn target;
032
033    private targetColumn caller;
034
035    private List<sourceColumn> sources;
036
037    private List<sourceColumn> callees;
038
039    private String processId;
040
041    private String processType;
042    
043    private String partition;
044
045    private String condition;
046
047    private String sqlHash;
048
049    private String sqlComment;
050    
051    private String procedureId;
052
053    private String timestampMin;
054
055    private String timestampMax;
056
057    private Boolean builtIn;
058    
059    private String callStmt;
060    
061        private String callCoordinate;
062
063    @XmlAttribute(required = false)
064    public String getId() {
065        return id;
066    }
067
068    public void setId(String id) {
069        this.id = id;
070    }
071
072    @XmlAttribute(required = false)
073    public String getType() {
074        return type;
075    }
076
077    public void setType(String type) {
078        this.type = type;
079    }
080
081    @XmlElement(name = "target", required = false)
082    public targetColumn getTarget() {
083        return target;
084    }
085
086    public void setTarget(targetColumn target) {
087        this.target = target;
088    }
089
090    @XmlElement(name = "source", required = false)
091    public List<sourceColumn> getSources() {
092        if (this.sources == null) {
093            this.sources = new ArrayList<sourceColumn>();
094        }
095        return sources;
096    }
097
098    public void setSources(List<sourceColumn> sources) {
099        this.sources = sources;
100    }
101
102    @XmlAttribute(required = false)
103    public String getClause() {
104        return clause;
105    }
106
107    public void setClause(String clause) {
108        this.clause = clause;
109    }
110
111    @XmlAttribute(required = false)
112    public String getCondition() {
113        return condition;
114    }
115
116    public void setCondition(String condition) {
117        this.condition = condition;
118    }
119
120    @XmlAttribute(required = false)
121    public String getJoinType() {
122        return joinType;
123    }
124
125    public void setJoinType(String joinType) {
126        this.joinType = joinType;
127    }
128
129    public boolean isDataFlow() {
130        return "fdd".equals(type);
131    }
132
133    @XmlAttribute(required = false)
134    public String getFunction() {
135        return function;
136    }
137
138    public void setFunction(String function) {
139        this.function = function;
140    }
141
142    @XmlAttribute(required = false)
143    public String getEffectType() {
144        return effectType;
145    }
146
147    public void setEffectType(String effectType) {
148        this.effectType = effectType;
149    }
150    
151    @XmlAttribute(required = false)
152    public String getPartition() {
153                return partition;
154        }
155
156        public void setPartition(String partition) {
157                this.partition = partition;
158        }
159
160        @Override
161    public Object clone() throws CloneNotSupportedException {
162        return super.clone();
163    }
164
165    @XmlAttribute(required = false)
166    public String getProcessId() {
167        return processId;
168    }
169
170    public void setProcessId(String processId) {
171        this.processId = processId;
172    }
173
174    @XmlAttribute(required = false)
175    public String getProcessType() {
176        return processType;
177    }
178
179    public void setProcessType(String processType) {
180        this.processType = processType;
181    }
182
183    @XmlAttribute(required = false)
184    public String getProcedureId() {
185                return procedureId;
186        }
187
188        public void setProcedureId(String procedureId) {
189                this.procedureId = procedureId;
190        }
191
192        @XmlAttribute(required = false)
193    public String getSqlHash() {
194        return sqlHash;
195    }
196
197    public void setSqlHash(String sqlHash) {
198        this.sqlHash = sqlHash;
199    }
200
201    @XmlAttribute(required = false)
202    public String getSqlComment() {
203        return sqlComment;
204    }
205
206    public void setSqlComment(String sqlComment) {
207        this.sqlComment = sqlComment;
208    }
209
210    @XmlAttribute(required = false)
211    public String getTimestampMin() {
212        return timestampMin;
213    }
214
215    public void setTimestampMin(String timestampMin) {
216        this.timestampMin = timestampMin;
217    }
218
219    @XmlAttribute(required = false)
220    public String getTimestampMax() {
221        return timestampMax;
222    }
223
224    public void setTimestampMax(String timestampMax) {
225        this.timestampMax = timestampMax;
226    }
227
228    @XmlElement(name = "caller", required = false)
229    public targetColumn getCaller() {
230        return caller;
231    }
232
233    public void setCaller(targetColumn caller) {
234        this.caller = caller;
235    }
236
237    @XmlElement(name = "callee", required = false)
238    public List<sourceColumn> getCallees() {
239        if (this.callees == null) {
240            this.callees = new ArrayList<sourceColumn>();
241        }
242        return callees;
243    }
244
245    public void setCallees(List<sourceColumn> callees) {
246        this.callees = callees;
247    }
248
249    @Override
250    public boolean equals(Object o) {
251        if (this == o) return true;
252        if (o == null || getClass() != o.getClass()) return false;
253        relationship that = (relationship) o;
254        return id.equals(that.id);
255    }
256
257    @Override
258    public int hashCode() {
259        return Objects.hash(id);
260    }
261
262    private Set<String> sourceIds = new HashSet<String>();
263        public void addSource(sourceColumn source) {
264                if(sourceIds.contains(source.getId())) {
265                        return;
266                }
267                getSources().add(source);
268                sourceIds.add(source.getId());
269        }
270
271    @XmlAttribute(required = false)
272    public Boolean getBuiltIn() {
273        return builtIn;
274    }
275
276    public void setBuiltIn(Boolean builtIn) {
277        this.builtIn = builtIn;
278    }
279
280    @XmlAttribute(required = false)
281        public String getCallStmt() {
282                return callStmt;
283        }
284
285        public void setCallStmt(String callStmt) {
286                this.callStmt = callStmt;
287        }
288
289    @XmlAttribute(required = false)
290        public String getCallCoordinate() {
291                return callCoordinate;
292        }
293
294        public void setCallCoordinate(String callCoordinate) {
295                this.callCoordinate = callCoordinate;
296        }
297
298        public String toDedupKey() {
299                StringBuilder sb = new StringBuilder(256);
300                appendDedupKey(sb);
301                return sb.toString();
302        }
303
304        public long toDedupHash() {
305                StringBuilder sb = new StringBuilder(256);
306                appendDedupKey(sb);
307                return SQLUtil.hash64(sb);
308        }
309
310        void appendDedupKey(StringBuilder sb) {
311                if (type != null) { sb.append("type=").append(type).append('|'); }
312                if (function != null) { sb.append("function=").append(function).append('|'); }
313                if (effectType != null) { sb.append("effectType=").append(effectType).append('|'); }
314                if (partition != null) { sb.append("partition=").append(partition).append('|'); }
315                if (clause != null) { sb.append("clause=").append(clause).append('|'); }
316                if (joinType != null) { sb.append("joinType=").append(joinType).append('|'); }
317                if (target != null) {
318                        sb.append("target={");
319                        target.appendDedupKey(sb);
320                        sb.append("}|");
321                }
322                if (caller != null) {
323                        sb.append("caller={");
324                        caller.appendDedupKey(sb);
325                        sb.append("}|");
326                }
327                if (sources != null && !sources.isEmpty()) {
328                        sb.append("sources=[");
329                        sources.stream().sorted(Comparator.comparing(sourceColumn::getId, Comparator.nullsFirst(Comparator.<String>naturalOrder())))
330                                        .forEach(s -> { sb.append('{'); s.appendDedupKey(sb); sb.append("},"); });
331                        sb.setLength(sb.length() - 1);
332                        sb.append("]|");
333                }
334                if (callees != null && !callees.isEmpty()) {
335                        sb.append("callees=[");
336                        callees.stream().sorted(Comparator.comparing(sourceColumn::getId, Comparator.nullsFirst(Comparator.<String>naturalOrder())))
337                                        .forEach(s -> { sb.append('{'); s.appendDedupKey(sb); sb.append("},"); });
338                        sb.setLength(sb.length() - 1);
339                        sb.append("]|");
340                }
341                if (processId != null) { sb.append("processId=").append(processId).append('|'); }
342                if (processType != null) { sb.append("processType=").append(processType).append('|'); }
343                if (procedureId != null) { sb.append("procedureId=").append(procedureId).append('|'); }
344                if (sqlHash != null) { sb.append("sqlHash=").append(sqlHash).append('|'); }
345                if (sqlComment != null) { sb.append("sqlComment=").append(sqlComment).append('|'); }
346                if (condition != null) { sb.append("condition=").append(condition).append('|'); }
347                if (timestampMin != null) { sb.append("timestampMin=").append(timestampMin).append('|'); }
348                if (timestampMax != null) { sb.append("timestampMax=").append(timestampMax).append('|'); }
349                if (builtIn != null) { sb.append("builtIn=").append(builtIn).append('|'); }
350                if (callStmt != null) { sb.append("callStmt=").append(callStmt).append('|'); }
351                sb.append("dataFlow=").append(isDataFlow()).append('|');
352                if (callCoordinate != null) { sb.append("callCoordinate=").append(callCoordinate).append('|'); }
353        }
354
355}