1
2
3
4
5
6
7
8
9
10 package org.jenkinsci.plugins.darcs;
11
12 import hudson.scm.ChangeLogSet;
13 import hudson.model.AbstractBuild;
14
15 import java.util.ArrayList;
16 import java.util.Iterator;
17 import java.util.List;
18 import java.util.Collections;
19 import java.util.Comparator;
20
21 import java.security.MessageDigest;
22 import java.security.NoSuchAlgorithmException;
23
24
25
26
27
28
29 public class DarcsChangeSetList extends ChangeLogSet<DarcsChangeSet> {
30
31
32
33
34 private static final String KIND = "darcs";
35
36
37
38 private static final int BYTE_MASK = 0xFF;
39
40
41
42
43 private final List<DarcsChangeSet> changeSets;
44
45
46
47 private String digest;
48
49
50
51
52 public DarcsChangeSetList() {
53 this(new ArrayList<DarcsChangeSet>());
54 }
55
56
57
58
59
60
61 public DarcsChangeSetList(final List<DarcsChangeSet> changes) {
62 this(null, changes);
63 }
64
65
66
67
68
69
70
71 @SuppressWarnings("LeakingThisInConstructor")
72 public DarcsChangeSetList(final AbstractBuild build, final List<DarcsChangeSet> changes) {
73 super(build);
74
75
76 Collections.sort(changes, new Comparator<DarcsChangeSet>() {
77 public int compare(DarcsChangeSet a, DarcsChangeSet b) {
78 return a.getHash().compareTo(b.getHash());
79 }
80 });
81 changeSets = Collections.unmodifiableList(changes);
82
83 for (final DarcsChangeSet log : changes) {
84 log.setParent(this);
85 }
86 }
87
88 @Override
89 public boolean isEmptySet() {
90 return getChangeSets().isEmpty();
91 }
92
93
94
95
96
97
98 public Iterator<DarcsChangeSet> iterator() {
99 return getChangeSets().iterator();
100 }
101
102
103
104
105
106
107 public int size() {
108 return getChangeSets().size();
109 }
110
111
112
113
114
115
116 public List<DarcsChangeSet> getChangeSets() {
117 return changeSets;
118 }
119
120
121
122
123
124
125 @Override
126 public String getKind() {
127 return KIND;
128 }
129
130
131
132
133
134
135
136
137 private String calcDigest() {
138 final StringBuilder res = new StringBuilder();
139
140 try {
141 final MessageDigest algorithm = MessageDigest.getInstance("MD5");
142 algorithm.reset();
143
144 if (isEmptySet()) {
145 algorithm.update("".getBytes());
146 } else {
147 for (final DarcsChangeSet cs : this) {
148 algorithm.update(cs.getHash().getBytes());
149 }
150 }
151
152 final byte[] md5 = algorithm.digest();
153
154 for (int i = 0; i < md5.length; i++) {
155 final String tmp = (Integer.toHexString(BYTE_MASK & md5[i]));
156
157 if (tmp.length() == 1) {
158 res.append("0");
159 }
160
161 res.append(tmp);
162 }
163 } catch (NoSuchAlgorithmException ex) {
164 res.append("");
165 }
166
167 return res.toString();
168 }
169
170
171
172
173
174
175
176
177 public String digest() {
178 if (null == digest) {
179 digest = calcDigest();
180 }
181
182 return digest;
183 }
184
185 @Override
186 public boolean equals(final Object object) {
187 if (!(object instanceof DarcsChangeSetList)) {
188 return false;
189 }
190
191 final DarcsChangeSetList other = (DarcsChangeSetList) object;
192 return digest().equals(other.digest());
193 }
194
195 @Override
196 public int hashCode() {
197 return digest().hashCode();
198 }
199
200 @Override
201 public String toString() {
202 return String.format("DarcsChangeSetList{changeSets=%s, digest=%s}", changeSets, digest());
203 }
204
205 }