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}