package gr.uom.java.xmi.diff; import java.util.List; import java.util.Set; import com.fasterxml.jackson.core.io.JsonStringEncoder; import com.fasterxml.jackson.core.util.BufferRecyclers; import gr.uom.java.xmi.LocationInfo; import gr.uom.java.xmi.LocationInfo.CodeElementType; import gr.uom.java.xmi.decomposition.AbstractCodeFragment; public class CodeRange { private String filePath; private int startLine; private int endLine; private int startColumn; private int endColumn; private CodeElementType codeElementType; private String description; private String codeElement; public CodeRange(String filePath, int startLine, int endLine, int startColumn, int endColumn, CodeElementType codeElementType) { this.filePath = filePath; this.startLine = startLine; this.endLine = endLine; this.startColumn = startColumn; this.endColumn = endColumn; this.codeElementType = codeElementType; } public String getFilePath() { return filePath; } public int getStartLine() { return startLine; } public int getEndLine() { return endLine; } public int getStartColumn() { return startColumn; } public int getEndColumn() { return endColumn; } public CodeElementType getCodeElementType() { return codeElementType; } public String getDescription() { return description; } public CodeRange setDescription(String description) { this.description = description; return this; } public String getCodeElement() { return codeElement; } public CodeRange setCodeElement(String codeElement) { this.codeElement = codeElement; return this; } public boolean subsumes(CodeRange other) { return this.filePath.equals(other.filePath) && this.startLine <= other.startLine && this.endLine >= other.endLine; } public boolean subsumes(List<? extends AbstractCodeFragment> statements) { int subsumedStatements = 0; for(AbstractCodeFragment statement : statements) { if(subsumes(statement.codeRange())) { subsumedStatements++; } } return subsumedStatements == statements.size(); } public String toString() { StringBuilder sb = new StringBuilder(); sb.append("{").append("\n"); encodeStringProperty(sb, "filePath", filePath, false); encodeIntProperty(sb, "startLine", startLine, false); encodeIntProperty(sb, "endLine", endLine, false); encodeIntProperty(sb, "startColumn", startColumn, false); encodeIntProperty(sb, "endColumn", endColumn, false); encodeStringProperty(sb, "codeElementType", codeElementType.name(), false); encodeStringProperty(sb, "description", description, false); encodeStringProperty(sb, "codeElement", escapeQuotes(codeElement), true); sb.append("}"); return sb.toString(); } private String escapeQuotes(String s) { if(s != null) { StringBuilder sb = new StringBuilder(); JsonStringEncoder encoder = BufferRecyclers.getJsonStringEncoder(); encoder.quoteAsString(s, sb); return sb.toString(); } return s; } private void encodeStringProperty(StringBuilder sb, String propertyName, String value, boolean last) { if(value != null) sb.append("\t").append("\t").append("\"" + propertyName + "\"" + ": " + "\"" + value + "\""); else sb.append("\t").append("\t").append("\"" + propertyName + "\"" + ": " + value); insertNewLine(sb, last); } private void encodeIntProperty(StringBuilder sb, String propertyName, int value, boolean last) { sb.append("\t").append("\t").append("\"" + propertyName + "\"" + ": " + value); insertNewLine(sb, last); } private void insertNewLine(StringBuilder sb, boolean last) { if(last) sb.append("\n"); else sb.append(",").append("\n"); } public static CodeRange computeRange(Set<AbstractCodeFragment> codeFragments) { String filePath = null; int minStartLine = 0; int maxEndLine = 0; int startColumn = 0; int endColumn = 0; for(AbstractCodeFragment fragment : codeFragments) { LocationInfo info = fragment.getLocationInfo(); filePath = info.getFilePath(); if(minStartLine == 0 || info.getStartLine() < minStartLine) { minStartLine = info.getStartLine(); startColumn = info.getStartColumn(); } if(info.getEndLine() > maxEndLine) { maxEndLine = info.getEndLine(); endColumn = info.getEndColumn(); } } return new CodeRange(filePath, minStartLine, maxEndLine, startColumn, endColumn, CodeElementType.LIST_OF_STATEMENTS); } }