001/*-----------------------------------------------------------------------+ 002 | com.teamscale.ui 003 | | 004 $Id$ 005 | | 006 | Copyright (c) 2009-2013 CQSE GmbH | 007 +-----------------------------------------------------------------------*/ 008package org.conqat.lib.commons.diff; 009 010import java.io.Serializable; 011import java.util.ArrayList; 012import java.util.List; 013 014import org.conqat.lib.commons.assertion.CCSMAssert; 015import org.conqat.lib.commons.collections.CollectionUtils; 016import org.conqat.lib.commons.collections.UnmodifiableList; 017import org.conqat.lib.commons.js_export.ExportToJavaScript; 018 019import com.fasterxml.jackson.annotation.JsonProperty; 020 021/** 022 * A class describing a diff. 023 */ 024@ExportToJavaScript 025public class DiffDescription implements Serializable { 026 027 /** Serial version UID. */ 028 private static final long serialVersionUID = 1; 029 030 /** The name of this description. */ 031 @JsonProperty("name") 032 private final String name; 033 034 /** 035 * Line changes for the left lines. The integers are organized in pairs, giving 036 * the start (inclusive) and end (exclusive) lines of a region. 037 */ 038 @JsonProperty("leftChangeLines") 039 private final List<Integer> leftChangeLines = new ArrayList<>(); 040 041 /** 042 * Line changes for the right lines. The integers are organized in pairs, giving 043 * the start (inclusive) and end (exclusive) lines of a region. 044 */ 045 @JsonProperty("rightChangeLines") 046 private final List<Integer> rightChangeLines = new ArrayList<>(); 047 048 /** 049 * Change tokens for the left text. These are used to highlight the exact change 050 * within changed lines. The integers are organized in pairs, giving the start 051 * (inclusive) and end (exclusive) offsets of a region. 052 */ 053 @JsonProperty("leftChangeRegions") 054 private final List<Integer> leftChangeRegions = new ArrayList<>(); 055 056 /** 057 * Change tokens for the left text. These are used to highlight the exact change 058 * within changed lines. The integers are organized in pairs, giving the start 059 * (inclusive) and end (exclusive) offsets of a region. 060 */ 061 @JsonProperty("rightChangeRegions") 062 private final List<Integer> rightChangeRegions = new ArrayList<>(); 063 064 /** Constructor. */ 065 public DiffDescription(String name) { 066 this.name = name; 067 } 068 069 /** Returns the name. */ 070 public String getName() { 071 return name; 072 } 073 074 /** 075 * Adds a line region that is matched between the left and right element. This 076 * denotes a part where these regions differ. First lines are inclusive, last 077 * lines are exclusive. All lines are 1-based. Adding regions must be performed 078 * in ascending order. 079 */ 080 public void addLineRegion(int leftFirstLine, int leftEndLine, int rightFirstLine, int rightEndLine) { 081 addLineRegion(leftFirstLine, leftEndLine, leftChangeLines); 082 addLineRegion(rightFirstLine, rightEndLine, rightChangeLines); 083 } 084 085 /** 086 * Inserts a line region into either {@link #leftChangeLines} or 087 * {@link #rightChangeLines}. 088 */ 089 private static void addLineRegion(int firstLine, int endLine, List<Integer> changeLines) { 090 CCSMAssert.isTrue(firstLine >= 0, "May only insert positive lines!"); 091 CCSMAssert.isTrue(firstLine <= endLine, "End must not be before start!"); 092 CCSMAssert.isTrue(changeLines.isEmpty() || CollectionUtils.getLast(changeLines) - 1 <= firstLine, 093 "Must insert in ascending order!"); 094 changeLines.add(firstLine); 095 changeLines.add(endLine); 096 } 097 098 /** 099 * Adds a change within a line region (that is highlighted) for the left side. 100 * Start is inclusive, end is exclusive. 101 */ 102 public void addLeftChange(int startOffset, int endOffset) { 103 addChange(startOffset, endOffset, leftChangeRegions); 104 } 105 106 /** 107 * Adds a change within a line region (that is highlighted) for the right side. 108 * Start is inclusive, end is exclusive. 109 */ 110 public void addRightChange(int startOffset, int endOffset) { 111 addChange(startOffset, endOffset, rightChangeRegions); 112 } 113 114 /** 115 * Adds a change within a line region. Start is inclusive, end is exclusive. 116 */ 117 private static void addChange(int startOffset, int endOffset, List<Integer> changeTokens) { 118 if (!changeTokens.isEmpty() && startOffset <= CollectionUtils.getLast(changeTokens)) { 119 changeTokens.set(changeTokens.size() - 1, endOffset); 120 } else { 121 changeTokens.add(startOffset); 122 changeTokens.add(endOffset); 123 } 124 } 125 126 /** 127 * Returns the change regions for the left lines. The integers are organized in 128 * pairs, giving the start (inclusive) and end (exclusive) index of a region. 129 */ 130 public UnmodifiableList<Integer> getLeftChangeRegions() { 131 return CollectionUtils.asUnmodifiable(leftChangeRegions); 132 } 133 134 /** 135 * Returns the change regions for the right lines. The integers are organized in 136 * pairs, giving the start (inclusive) and end (exclusive) index of a region. 137 */ 138 public UnmodifiableList<Integer> getRightChangeRegions() { 139 return CollectionUtils.asUnmodifiable(rightChangeRegions); 140 } 141 142 /** 143 * Adds the given list to the leftChangeRegions 144 */ 145 public void addLeftChangeRegions(UnmodifiableList<Integer> leftChangeRegions) { 146 this.leftChangeRegions.addAll(leftChangeRegions); 147 } 148 149 /** 150 * Adds the given list to the rightChangeRegions 151 */ 152 public void addRightChangeRegions(UnmodifiableList<Integer> rightChangeRegions) { 153 this.rightChangeRegions.addAll(rightChangeRegions); 154 } 155 156 /** 157 * Returns the line changes for the left lines. The integers are organized in 158 * pairs, giving the start (inclusive) and end (exclusive) lines of a region. 159 */ 160 public UnmodifiableList<Integer> getLeftChangeLines() { 161 return CollectionUtils.asUnmodifiable(leftChangeLines); 162 } 163 164 /** 165 * Returns the line changes for the right lines. The integers are organized in 166 * pairs, giving the start (inclusive) and end (exclusive) lines of a region. 167 */ 168 public UnmodifiableList<Integer> getRightChangeLines() { 169 return CollectionUtils.asUnmodifiable(rightChangeLines); 170 } 171}