Classes in this File | Line Coverage | Branch Coverage | Complexity | ||||
ClassReport |
|
| 2.6231884057971016;2.623 |
1 | /* | |
2 | * Copyright (c) 2001-2009, Jean Tessier | |
3 | * All rights reserved. | |
4 | * | |
5 | * Redistribution and use in source and binary forms, with or without | |
6 | * modification, are permitted provided that the following conditions | |
7 | * are met: | |
8 | * | |
9 | * * Redistributions of source code must retain the above copyright | |
10 | * notice, this list of conditions and the following disclaimer. | |
11 | * | |
12 | * * Redistributions in binary form must reproduce the above copyright | |
13 | * notice, this list of conditions and the following disclaimer in the | |
14 | * documentation and/or other materials provided with the distribution. | |
15 | * | |
16 | * * Neither the name of Jean Tessier nor the names of his contributors | |
17 | * may be used to endorse or promote products derived from this software | |
18 | * without specific prior written permission. | |
19 | * | |
20 | * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS | |
21 | * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT | |
22 | * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR | |
23 | * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR | |
24 | * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, | |
25 | * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, | |
26 | * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR | |
27 | * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF | |
28 | * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING | |
29 | * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS | |
30 | * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | |
31 | */ | |
32 | ||
33 | package com.jeantessier.diff; | |
34 | ||
35 | import java.util.*; | |
36 | ||
37 | import org.apache.oro.text.perl.*; | |
38 | ||
39 | import com.jeantessier.classreader.*; | |
40 | ||
41 | 24 | public class ClassReport extends Printer implements Comparable, com.jeantessier.classreader.Visitor { |
42 | 1 | private static final Perl5Util perl = new Perl5Util(); |
43 | ||
44 | private ClassDifferences differences; | |
45 | ||
46 | 24 | private Collection<FeatureDifferences> removedFields = new TreeSet<FeatureDifferences>(); |
47 | 24 | private Collection<FeatureDifferences> removedConstructors = new TreeSet<FeatureDifferences>(); |
48 | 24 | private Collection<FeatureDifferences> removedMethods = new TreeSet<FeatureDifferences>(); |
49 | ||
50 | 24 | private Collection<FeatureDifferences> deprecatedFields = new TreeSet<FeatureDifferences>(); |
51 | 24 | private Collection<FeatureDifferences> deprecatedConstructors = new TreeSet<FeatureDifferences>(); |
52 | 24 | private Collection<FeatureDifferences> deprecatedMethods = new TreeSet<FeatureDifferences>(); |
53 | ||
54 | 24 | private Collection<FieldDifferences> modifiedFields = new TreeSet<FieldDifferences>(); |
55 | 24 | private Collection<CodeDifferences> modifiedConstructors = new TreeSet<CodeDifferences>(); |
56 | 24 | private Collection<CodeDifferences> modifiedMethods = new TreeSet<CodeDifferences>(); |
57 | ||
58 | 24 | private Collection<FeatureDifferences> undeprecatedFields = new TreeSet<FeatureDifferences>(); |
59 | 24 | private Collection<FeatureDifferences> undeprecatedConstructors = new TreeSet<FeatureDifferences>(); |
60 | 24 | private Collection<FeatureDifferences> undeprecatedMethods = new TreeSet<FeatureDifferences>(); |
61 | ||
62 | 24 | private Collection<FeatureDifferences> newFields = new TreeSet<FeatureDifferences>(); |
63 | 24 | private Collection<FeatureDifferences> newConstructors = new TreeSet<FeatureDifferences>(); |
64 | 24 | private Collection<FeatureDifferences> newMethods = new TreeSet<FeatureDifferences>(); |
65 | ||
66 | public void visitClassDifferences(ClassDifferences differences) { | |
67 | 22 | this.differences = differences; |
68 | ||
69 | 22 | for (Differences featureDifference : differences.getFeatureDifferences()) { |
70 | 56 | featureDifference.accept(this); |
71 | } | |
72 | 22 | } |
73 | ||
74 | public void visitInterfaceDifferences(InterfaceDifferences differences) { | |
75 | 2 | this.differences = differences; |
76 | ||
77 | 2 | for (Differences featureDifference : differences.getFeatureDifferences()) { |
78 | 11 | featureDifference.accept(this); |
79 | } | |
80 | 2 | } |
81 | ||
82 | public void visitFieldDifferences(FieldDifferences differences) { | |
83 | 47 | if (differences.isRemoved()) { |
84 | 14 | removedFields.add(differences); |
85 | } | |
86 | ||
87 | 47 | if (differences.isModified()) { |
88 | 15 | modifiedFields.add(differences); |
89 | } | |
90 | ||
91 | 47 | if (differences.isNew()) { |
92 | 14 | newFields.add(differences); |
93 | } | |
94 | ||
95 | 47 | if (isDeprecated()) { |
96 | 2 | deprecatedFields.add(differences); |
97 | } | |
98 | ||
99 | 47 | if (isUndeprecated()) { |
100 | 2 | undeprecatedFields.add(differences); |
101 | } | |
102 | 47 | } |
103 | ||
104 | public void visitConstructorDifferences(ConstructorDifferences differences) { | |
105 | 6 | if (differences.isRemoved()) { |
106 | 1 | removedConstructors.add(differences); |
107 | } | |
108 | ||
109 | 6 | if (differences.isModified()) { |
110 | 2 | modifiedConstructors.add(differences); |
111 | } | |
112 | ||
113 | 6 | if (differences.isNew()) { |
114 | 1 | newConstructors.add(differences); |
115 | } | |
116 | ||
117 | 6 | if (isDeprecated()) { |
118 | 1 | deprecatedConstructors.add(differences); |
119 | } | |
120 | ||
121 | 6 | if (isUndeprecated()) { |
122 | 1 | undeprecatedConstructors.add(differences); |
123 | } | |
124 | 6 | } |
125 | ||
126 | public void visitMethodDifferences(MethodDifferences differences) { | |
127 | 14 | if (differences.isRemoved()) { |
128 | 2 | removedMethods.add(differences); |
129 | } | |
130 | ||
131 | 14 | if (differences.isModified()) { |
132 | 4 | modifiedMethods.add(differences); |
133 | } | |
134 | ||
135 | 14 | if (differences.isNew()) { |
136 | 4 | newMethods.add(differences); |
137 | } | |
138 | ||
139 | 14 | if (isDeprecated()) { |
140 | 2 | deprecatedMethods.add(differences); |
141 | } | |
142 | ||
143 | 14 | if (isUndeprecated()) { |
144 | 2 | undeprecatedMethods.add(differences); |
145 | } | |
146 | 14 | } |
147 | ||
148 | public void visitClassfiles(Collection<Classfile> classfiles) { | |
149 | // Do nothing | |
150 | 0 | } |
151 | ||
152 | public void visitClassfile(Classfile classfile) { | |
153 | // Do nothing | |
154 | 0 | } |
155 | ||
156 | public void visitConstantPool(ConstantPool constantPool) { | |
157 | // Do nothing | |
158 | 0 | } |
159 | ||
160 | public void visitClass_info(Class_info entry) { | |
161 | // Do nothing | |
162 | 0 | } |
163 | ||
164 | public void visitFieldRef_info(FieldRef_info entry) { | |
165 | // Do nothing | |
166 | 0 | } |
167 | ||
168 | public void visitMethodRef_info(MethodRef_info entry) { | |
169 | // Do nothing | |
170 | 0 | } |
171 | ||
172 | public void visitInterfaceMethodRef_info(InterfaceMethodRef_info entry) { | |
173 | // Do nothing | |
174 | 0 | } |
175 | ||
176 | public void visitString_info(String_info entry) { | |
177 | 36 | entry.getRawValue().accept(this); |
178 | 36 | } |
179 | ||
180 | public void visitInteger_info(Integer_info entry) { | |
181 | 17 | append(entry.getValue()); |
182 | 17 | } |
183 | ||
184 | public void visitFloat_info(Float_info entry) { | |
185 | 1 | append(entry.getValue()); |
186 | 1 | } |
187 | ||
188 | public void visitLong_info(Long_info entry) { | |
189 | 0 | append(entry.getValue()); |
190 | 0 | } |
191 | ||
192 | public void visitDouble_info(Double_info entry) { | |
193 | 0 | append(entry.getValue()); |
194 | 0 | } |
195 | ||
196 | public void visitNameAndType_info(NameAndType_info entry) { | |
197 | // Do nothing | |
198 | 0 | } |
199 | ||
200 | public void visitUTF8_info(UTF8_info entry) { | |
201 | 36 | append(escapeXMLCharactersInAttributeValue(entry.getValue())); |
202 | 36 | } |
203 | ||
204 | public void visitField_info(Field_info entry) { | |
205 | 58 | if (entry.isPublic()) append(" visibility=\"public\""); |
206 | 58 | if (entry.isProtected()) append(" visibility=\"protected\""); |
207 | 58 | if (entry.isPackage()) append(" visibility=\"package\""); |
208 | 58 | if (entry.isPrivate()) append(" visibility=\"private\""); |
209 | 58 | if (entry.isStatic()) append(" static=\"yes\""); |
210 | 58 | if (entry.isFinal()) append(" final=\"yes\""); |
211 | 58 | if (entry.isVolatile()) append(" volatile=\"yes\""); |
212 | 58 | if (entry.isTransient()) append(" transient=\"yes\""); |
213 | 58 | if (entry.isSynthetic()) append(" synthetic=\"yes\""); |
214 | 58 | if (entry.isDeprecated()) append(" deprecated=\"yes\""); |
215 | ||
216 | 58 | append(" type=\"").append(entry.getType()).append("\""); |
217 | 58 | append(" name=\"").append(entry.getName()).append("\""); |
218 | 58 | append(" signature=\"").append(entry.getSignature()).append("\""); |
219 | 58 | append(" full-signature=\"").append(entry.getFullSignature()).append("\""); |
220 | ||
221 | 58 | if (entry.getConstantValue() != null) { |
222 | 54 | append(" value=\""); |
223 | 54 | entry.getConstantValue().accept(this); |
224 | 54 | append("\""); |
225 | } | |
226 | 58 | } |
227 | ||
228 | public void visitMethod_info(Method_info entry) { | |
229 | // Do nothing | |
230 | 0 | } |
231 | ||
232 | public void visitConstantValue_attribute(ConstantValue_attribute attribute) { | |
233 | 54 | attribute.getRawValue().accept(this); |
234 | 54 | } |
235 | ||
236 | public void visitCode_attribute(Code_attribute attribute) { | |
237 | // Do nothing | |
238 | 0 | } |
239 | ||
240 | public void visitExceptions_attribute(Exceptions_attribute attribute) { | |
241 | // Do nothing | |
242 | 0 | } |
243 | ||
244 | public void visitInnerClasses_attribute(InnerClasses_attribute attribute) { | |
245 | // Do nothing | |
246 | 0 | } |
247 | ||
248 | public void visitEnclosingMethod_attribute(EnclosingMethod_attribute attribute) { | |
249 | // Do nothing | |
250 | 0 | } |
251 | ||
252 | public void visitSynthetic_attribute(Synthetic_attribute attribute) { | |
253 | // Do nothing | |
254 | 0 | } |
255 | ||
256 | public void visitSignature_attribute(Signature_attribute attribute) { | |
257 | // Do nothing | |
258 | 0 | } |
259 | ||
260 | public void visitSourceFile_attribute(SourceFile_attribute attribute) { | |
261 | // Do nothing | |
262 | 0 | } |
263 | ||
264 | public void visitSourceDebugExtension_attribute(SourceDebugExtension_attribute attribute) { | |
265 | // Do nothing | |
266 | 0 | } |
267 | ||
268 | public void visitLineNumberTable_attribute(LineNumberTable_attribute attribute) { | |
269 | // Do nothing | |
270 | 0 | } |
271 | ||
272 | public void visitLocalVariableTable_attribute(LocalVariableTable_attribute attribute) { | |
273 | // Do nothing | |
274 | 0 | } |
275 | ||
276 | public void visitLocalVariableTypeTable_attribute(LocalVariableTypeTable_attribute attribute) { | |
277 | // Do nothing | |
278 | 0 | } |
279 | ||
280 | public void visitDeprecated_attribute(Deprecated_attribute attribute) { | |
281 | // Do nothing | |
282 | 0 | } |
283 | ||
284 | public void visitRuntimeVisibleAnnotations_attribute(RuntimeVisibleAnnotations_attribute attribute) { | |
285 | // Do nothing | |
286 | 0 | } |
287 | ||
288 | public void visitRuntimeInvisibleAnnotations_attribute(RuntimeInvisibleAnnotations_attribute attribute) { | |
289 | // Do nothing | |
290 | 0 | } |
291 | ||
292 | public void visitRuntimeVisibleParameterAnnotations_attribute(RuntimeVisibleParameterAnnotations_attribute attribute) { | |
293 | // Do nothing | |
294 | 0 | } |
295 | ||
296 | public void visitRuntimeInvisibleParameterAnnotations_attribute(RuntimeInvisibleParameterAnnotations_attribute attribute) { | |
297 | // Do nothing | |
298 | 0 | } |
299 | ||
300 | public void visitAnnotationDefault_attribute(AnnotationDefault_attribute attribute) { | |
301 | // Do nothing | |
302 | 0 | } |
303 | ||
304 | public void visitCustom_attribute(Custom_attribute attribute) { | |
305 | // Do nothing | |
306 | 0 | } |
307 | ||
308 | public void visitInstruction(Instruction instruction) { | |
309 | // Do nothing | |
310 | 0 | } |
311 | ||
312 | public void visitExceptionHandler(ExceptionHandler helper) { | |
313 | // Do nothing | |
314 | 0 | } |
315 | ||
316 | public void visitInnerClass(InnerClass helper) { | |
317 | // Do nothing | |
318 | 0 | } |
319 | ||
320 | public void visitLineNumber(LineNumber helper) { | |
321 | // Do nothing | |
322 | 0 | } |
323 | ||
324 | public void visitLocalVariable(LocalVariable helper) { | |
325 | // Do nothing | |
326 | 0 | } |
327 | ||
328 | public void visitLocalVariableType(LocalVariableType helper) { | |
329 | // Do nothing | |
330 | 0 | } |
331 | ||
332 | public void visitParameter(Parameter helper) { | |
333 | // Do nothing | |
334 | 0 | } |
335 | ||
336 | public void visitAnnotation(Annotation helper) { | |
337 | // Do nothing | |
338 | 0 | } |
339 | ||
340 | public void visitElementValuePair(ElementValuePair helper) { | |
341 | // Do nothing | |
342 | 0 | } |
343 | ||
344 | public void visitByteConstantElementValue(ByteConstantElementValue helper) { | |
345 | // Do nothing | |
346 | 0 | } |
347 | ||
348 | public void visitCharConstantElementValue(CharConstantElementValue helper) { | |
349 | // Do nothing | |
350 | 0 | } |
351 | ||
352 | public void visitDoubleConstantElementValue(DoubleConstantElementValue helper) { | |
353 | // Do nothing | |
354 | 0 | } |
355 | ||
356 | public void visitFloatConstantElementValue(FloatConstantElementValue helper) { | |
357 | // Do nothing | |
358 | 0 | } |
359 | ||
360 | public void visitIntegerConstantElementValue(IntegerConstantElementValue helper) { | |
361 | // Do nothing | |
362 | 0 | } |
363 | ||
364 | public void visitLongConstantElementValue(LongConstantElementValue helper) { | |
365 | // Do nothing | |
366 | 0 | } |
367 | ||
368 | public void visitShortConstantElementValue(ShortConstantElementValue helper) { | |
369 | // Do nothing | |
370 | 0 | } |
371 | ||
372 | public void visitBooleanConstantElementValue(BooleanConstantElementValue helper) { | |
373 | // Do nothing | |
374 | 0 | } |
375 | ||
376 | public void visitStringConstantElementValue(StringConstantElementValue helper) { | |
377 | // Do nothing | |
378 | 0 | } |
379 | ||
380 | public void visitEnumElementValue(EnumElementValue helper) { | |
381 | // Do nothing | |
382 | 0 | } |
383 | ||
384 | public void visitClassElementValue(ClassElementValue helper) { | |
385 | // Do nothing | |
386 | 0 | } |
387 | ||
388 | public void visitAnnotationElementValue(AnnotationElementValue helper) { | |
389 | // Do nothing | |
390 | 0 | } |
391 | ||
392 | public void visitArrayElementValue(ArrayElementValue helper) { | |
393 | // Do nothing | |
394 | 0 | } |
395 | ||
396 | public String render() { | |
397 | 24 | raiseIndent(); |
398 | 24 | raiseIndent(); |
399 | ||
400 | 24 | indent().append("<class>").eol(); |
401 | 24 | raiseIndent(); |
402 | ||
403 | 24 | indent().append("<name>").append(differences.getName()).append("</name>").eol(); |
404 | ||
405 | 24 | if (differences.isDeclarationModified()) { |
406 | 2 | indent().append("<modified-declaration>").eol(); |
407 | 2 | raiseIndent(); |
408 | ||
409 | 2 | indent().append("<old-declaration").append(breakdownDeclaration(differences.getOldClass())).append(">").append(differences.getOldDeclaration()).append("</old-declaration>").eol(); |
410 | 2 | indent().append("<new-declaration").append(breakdownDeclaration(differences.getNewClass())).append(">").append(differences.getNewDeclaration()).append("</new-declaration>").eol(); |
411 | ||
412 | 2 | lowerIndent(); |
413 | 2 | indent().append("</modified-declaration>").eol(); |
414 | } | |
415 | ||
416 | 24 | if (removedFields.size() != 0) { |
417 | 8 | indent().append("<removed-fields>").eol(); |
418 | 8 | raiseIndent(); |
419 | ||
420 | 8 | for (FeatureDifferences fd : removedFields) { |
421 | 14 | indent(); |
422 | 14 | append("<declaration"); |
423 | 14 | fd.getOldFeature().accept(this); |
424 | 14 | if (fd.isInherited()) { |
425 | 0 | append(" inherited=\"yes\""); |
426 | } | |
427 | 14 | append(">"); |
428 | 14 | append(fd.getOldDeclaration()); |
429 | 14 | append("</declaration>"); |
430 | 14 | eol(); |
431 | } | |
432 | ||
433 | 8 | lowerIndent(); |
434 | 8 | indent().append("</removed-fields>").eol(); |
435 | } | |
436 | ||
437 | 24 | if (removedConstructors.size() != 0) { |
438 | 1 | indent().append("<removed-constructors>").eol(); |
439 | 1 | raiseIndent(); |
440 | ||
441 | 1 | for (FeatureDifferences fd : removedConstructors) { |
442 | 1 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getOldFeature())).append(fd.isInherited() ? " inherited=\"yes\"" : "").append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
443 | } | |
444 | ||
445 | 1 | lowerIndent(); |
446 | 1 | indent().append("</removed-constructors>").eol(); |
447 | } | |
448 | ||
449 | 24 | if (removedMethods.size() != 0) { |
450 | 2 | indent().append("<removed-methods>").eol(); |
451 | 2 | raiseIndent(); |
452 | ||
453 | 2 | for (FeatureDifferences fd : removedMethods) { |
454 | 2 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getOldFeature())).append(fd.isInherited() ? " inherited=\"yes\"" : "").append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
455 | } | |
456 | ||
457 | 2 | lowerIndent(); |
458 | 2 | indent().append("</removed-methods>").eol(); |
459 | } | |
460 | ||
461 | 24 | if (deprecatedFields.size() != 0) { |
462 | 2 | indent().append("<deprecated-fields>").eol(); |
463 | 2 | raiseIndent(); |
464 | ||
465 | 2 | for (FeatureDifferences fd : deprecatedFields) { |
466 | 2 | indent().append("<declaration").append(breakdownDeclaration((Field_info) fd.getNewFeature())).append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
467 | } | |
468 | ||
469 | 2 | lowerIndent(); |
470 | 2 | indent().append("</deprecated-fields>").eol(); |
471 | } | |
472 | ||
473 | 24 | if (deprecatedConstructors.size() != 0) { |
474 | 1 | indent().append("<deprecated-constructors>").eol(); |
475 | 1 | raiseIndent(); |
476 | ||
477 | 1 | for (FeatureDifferences fd : deprecatedConstructors) { |
478 | 1 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getNewFeature())).append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
479 | } | |
480 | ||
481 | 1 | lowerIndent(); |
482 | 1 | indent().append("</deprecated-constructors>").eol(); |
483 | } | |
484 | ||
485 | 24 | if (deprecatedMethods.size() != 0) { |
486 | 2 | indent().append("<deprecated-methods>").eol(); |
487 | 2 | raiseIndent(); |
488 | ||
489 | 2 | for (FeatureDifferences fd : deprecatedMethods) { |
490 | 2 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getNewFeature())).append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
491 | } | |
492 | ||
493 | 2 | lowerIndent(); |
494 | 2 | indent().append("</deprecated-methods>").eol(); |
495 | } | |
496 | ||
497 | 24 | if (modifiedFields.size() != 0) { |
498 | 8 | indent().append("<modified-fields>").eol(); |
499 | 8 | raiseIndent(); |
500 | ||
501 | 8 | for (FieldDifferences fd : modifiedFields) { |
502 | 15 | indent().append("<feature>").eol(); |
503 | 15 | raiseIndent(); |
504 | ||
505 | 15 | indent().append("<name>").append(fd.getName()).append("</name>").eol(); |
506 | ||
507 | 15 | indent().append("<modified-declaration>").eol(); |
508 | 15 | raiseIndent(); |
509 | ||
510 | 15 | Field_info oldField = (Field_info) fd.getOldFeature(); |
511 | 15 | indent(); |
512 | 15 | append("<old-declaration"); |
513 | 15 | oldField.accept(this); |
514 | 15 | append(">"); |
515 | 15 | if (fd.isConstantValueDifference()) { |
516 | 14 | append(escapeXMLCharactersInTagContent(oldField.getFullDeclaration())); |
517 | } else { | |
518 | 1 | append(oldField.getDeclaration()); |
519 | } | |
520 | 15 | append("</old-declaration>"); |
521 | 15 | eol(); |
522 | ||
523 | 15 | Field_info newField = (Field_info) fd.getNewFeature(); |
524 | 15 | indent(); |
525 | 15 | append("<new-declaration"); |
526 | 15 | newField.accept(this); |
527 | 15 | append(">"); |
528 | 15 | if (fd.isConstantValueDifference()) { |
529 | 14 | append(escapeXMLCharactersInTagContent(newField.getFullDeclaration())); |
530 | } else { | |
531 | 1 | append(newField.getDeclaration()); |
532 | } | |
533 | 15 | append("</new-declaration>"); |
534 | 15 | eol(); |
535 | ||
536 | 15 | lowerIndent(); |
537 | 15 | indent().append("</modified-declaration>").eol(); |
538 | ||
539 | 15 | lowerIndent(); |
540 | 15 | indent().append("</feature>").eol(); |
541 | 15 | } |
542 | ||
543 | 8 | lowerIndent(); |
544 | 8 | indent().append("</modified-fields>").eol(); |
545 | } | |
546 | ||
547 | 24 | if (modifiedConstructors.size() != 0) { |
548 | 1 | indent().append("<modified-constructors>").eol(); |
549 | 1 | raiseIndent(); |
550 | ||
551 | 1 | for (CodeDifferences cd : modifiedConstructors) { |
552 | 2 | indent().append("<feature>").eol(); |
553 | 2 | raiseIndent(); |
554 | ||
555 | 2 | indent().append("<name>").append(cd.getName()).append("</name>").eol(); |
556 | ||
557 | 2 | if (!cd.getOldDeclaration().equals(cd.getNewDeclaration())) { |
558 | 1 | indent().append("<modified-declaration>").eol(); |
559 | 1 | raiseIndent(); |
560 | 1 | indent().append("<old-declaration").append(breakdownDeclaration((Method_info) cd.getOldFeature())).append(">").append(cd.getOldDeclaration()).append("</old-declaration>").eol(); |
561 | 1 | indent().append("<new-declaration").append(breakdownDeclaration((Method_info) cd.getNewFeature())).append(">").append(cd.getNewDeclaration()).append("</new-declaration>").eol(); |
562 | 1 | lowerIndent(); |
563 | 1 | indent().append("</modified-declaration>").eol(); |
564 | } | |
565 | ||
566 | 2 | if (cd.isCodeDifference()) { |
567 | 1 | indent().append("<modified-code").append(breakdownDeclaration((Method_info) cd.getNewFeature())).append(">").append(cd.getNewDeclaration()).append("</modified-code>").eol(); |
568 | } | |
569 | ||
570 | 2 | lowerIndent(); |
571 | 2 | indent().append("</feature>").eol(); |
572 | } | |
573 | ||
574 | 1 | lowerIndent(); |
575 | 1 | indent().append("</modified-constructors>").eol(); |
576 | } | |
577 | ||
578 | 24 | if (modifiedMethods.size() != 0) { |
579 | 3 | indent().append("<modified-methods>").eol(); |
580 | 3 | raiseIndent(); |
581 | ||
582 | 3 | for (CodeDifferences md : modifiedMethods) { |
583 | 4 | indent().append("<feature>").eol(); |
584 | 4 | raiseIndent(); |
585 | ||
586 | 4 | indent().append("<name>").append(md.getName()).append("</name>").eol(); |
587 | ||
588 | 4 | if (!md.getOldDeclaration().equals(md.getNewDeclaration())) { |
589 | 3 | indent().append("<modified-declaration>").eol(); |
590 | 3 | raiseIndent(); |
591 | 3 | indent().append("<old-declaration").append(breakdownDeclaration((Method_info) md.getOldFeature())).append(">").append(md.getOldDeclaration()).append("</old-declaration>").eol(); |
592 | 3 | indent().append("<new-declaration").append(breakdownDeclaration((Method_info) md.getNewFeature())).append(">").append(md.getNewDeclaration()).append("</new-declaration>").eol(); |
593 | 3 | lowerIndent(); |
594 | 3 | indent().append("</modified-declaration>").eol(); |
595 | } | |
596 | ||
597 | 4 | if (md.isCodeDifference()) { |
598 | 2 | indent().append("<modified-code").append(breakdownDeclaration((Method_info) md.getNewFeature())).append(">").append(md.getNewDeclaration()).append("</modified-code>").eol(); |
599 | } | |
600 | ||
601 | 4 | lowerIndent(); |
602 | 4 | indent().append("</feature>").eol(); |
603 | } | |
604 | ||
605 | 3 | lowerIndent(); |
606 | 3 | indent().append("</modified-methods>").eol(); |
607 | } | |
608 | ||
609 | 24 | if (undeprecatedFields.size() != 0) { |
610 | 2 | indent().append("<undeprecated-fields>").eol(); |
611 | 2 | raiseIndent(); |
612 | ||
613 | 2 | for (FeatureDifferences fd : undeprecatedFields) { |
614 | 2 | indent().append("<declaration").append(breakdownDeclaration((Field_info) fd.getNewFeature())).append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
615 | } | |
616 | ||
617 | 2 | lowerIndent(); |
618 | 2 | indent().append("</undeprecated-fields>").eol(); |
619 | } | |
620 | ||
621 | 24 | if (undeprecatedConstructors.size() != 0) { |
622 | 1 | indent().append("<undeprecated-constructors>").eol(); |
623 | 1 | raiseIndent(); |
624 | ||
625 | 1 | for (FeatureDifferences fd : undeprecatedConstructors) { |
626 | 1 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getNewFeature())).append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
627 | } | |
628 | ||
629 | 1 | lowerIndent(); |
630 | 1 | indent().append("</undeprecated-constructors>").eol(); |
631 | } | |
632 | ||
633 | 24 | if (undeprecatedMethods.size() != 0) { |
634 | 2 | indent().append("<undeprecated-methods>").eol(); |
635 | 2 | raiseIndent(); |
636 | ||
637 | 2 | for (FeatureDifferences fd : undeprecatedMethods) { |
638 | 2 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getNewFeature())).append(">").append(fd.getOldDeclaration()).append("</declaration>").eol(); |
639 | } | |
640 | ||
641 | 2 | lowerIndent(); |
642 | 2 | indent().append("</undeprecated-methods>").eol(); |
643 | } | |
644 | ||
645 | 24 | if (newFields.size() != 0) { |
646 | 8 | indent().append("<new-fields>").eol(); |
647 | 8 | raiseIndent(); |
648 | ||
649 | 8 | for (FeatureDifferences fd : newFields) { |
650 | 14 | indent(); |
651 | 14 | append("<declaration"); |
652 | 14 | fd.getNewFeature().accept(this); |
653 | 14 | append(">"); |
654 | 14 | append(fd.getNewDeclaration()); |
655 | 14 | append("</declaration>"); |
656 | 14 | eol(); |
657 | } | |
658 | ||
659 | 8 | lowerIndent(); |
660 | 8 | indent().append("</new-fields>").eol(); |
661 | } | |
662 | ||
663 | 24 | if (newConstructors.size() != 0) { |
664 | 1 | indent().append("<new-constructors>").eol(); |
665 | 1 | raiseIndent(); |
666 | ||
667 | 1 | for (FeatureDifferences fd : newConstructors) { |
668 | 1 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getNewFeature())).append(">").append(fd.getNewDeclaration()).append("</declaration>").eol(); |
669 | } | |
670 | ||
671 | 1 | lowerIndent(); |
672 | 1 | indent().append("</new-constructors>").eol(); |
673 | } | |
674 | ||
675 | 24 | if (newMethods.size() != 0) { |
676 | 3 | indent().append("<new-methods>").eol(); |
677 | 3 | raiseIndent(); |
678 | ||
679 | 3 | for (FeatureDifferences fd : newMethods) { |
680 | 4 | indent().append("<declaration").append(breakdownDeclaration((Method_info) fd.getNewFeature())).append(">").append(fd.getNewDeclaration()).append("</declaration>").eol(); |
681 | } | |
682 | ||
683 | 3 | lowerIndent(); |
684 | 3 | indent().append("</new-methods>").eol(); |
685 | } | |
686 | ||
687 | 24 | lowerIndent(); |
688 | 24 | indent().append("</class>").eol(); |
689 | ||
690 | 24 | lowerIndent(); |
691 | 24 | lowerIndent(); |
692 | ||
693 | 24 | return super.toString(); |
694 | } | |
695 | ||
696 | private String breakdownDeclaration(Classfile element) { | |
697 | 4 | StringBuffer result = new StringBuffer(); |
698 | ||
699 | 4 | if (element != null) { |
700 | 4 | if (element.isPublic()) result.append(" visibility=\"public\""); |
701 | 4 | if (element.isPackage()) result.append(" visibility=\"package\""); |
702 | 4 | if (element.isFinal()) result.append(" final=\"yes\""); |
703 | 4 | if (element.isSuper()) result.append(" super=\"yes\""); |
704 | 4 | if (element.isSynthetic()) result.append(" synthetic=\"yes\""); |
705 | 4 | if (element.isDeprecated()) result.append(" deprecated=\"yes\""); |
706 | ||
707 | 4 | result.append(" name=\"").append(element.getClassName()).append("\""); |
708 | ||
709 | 4 | if (element.isInterface()) { |
710 | 2 | result.append(" interface=\"yes\""); |
711 | ||
712 | 2 | result.append(" extends=\""); |
713 | 2 | Iterator i = element.getAllInterfaces().iterator(); |
714 | 3 | while (i.hasNext()) { |
715 | 1 | result.append(i.next()); |
716 | 1 | if (i.hasNext()) { |
717 | 0 | result.append(", "); |
718 | } | |
719 | } | |
720 | 2 | result.append("\""); |
721 | 2 | } else { |
722 | 2 | if (element.isAbstract()) result.append(" abstract=\"yes\""); |
723 | ||
724 | 2 | result.append(" extends=\"").append(element.getSuperclassName()).append("\""); |
725 | ||
726 | 2 | result.append(" implements=\""); |
727 | 2 | Iterator i = element.getAllInterfaces().iterator(); |
728 | 3 | while (i.hasNext()) { |
729 | 1 | result.append(i.next()); |
730 | 1 | if (i.hasNext()) { |
731 | 0 | result.append(", "); |
732 | } | |
733 | } | |
734 | 2 | result.append("\""); |
735 | } | |
736 | } | |
737 | ||
738 | 4 | return result.toString(); |
739 | } | |
740 | ||
741 | private String breakdownDeclaration(Field_info element) { | |
742 | 4 | StringBuffer result = new StringBuffer(); |
743 | ||
744 | 4 | if (element != null) { |
745 | 4 | if (element.isPublic()) result.append(" visibility=\"public\""); |
746 | 4 | if (element.isProtected()) result.append(" visibility=\"protected\""); |
747 | 4 | if (element.isPackage()) result.append(" visibility=\"package\""); |
748 | 4 | if (element.isPrivate()) result.append(" visibility=\"private\""); |
749 | 4 | if (element.isStatic()) result.append(" static=\"yes\""); |
750 | 4 | if (element.isFinal()) result.append(" final=\"yes\""); |
751 | 4 | if (element.isVolatile()) result.append(" volatile=\"yes\""); |
752 | 4 | if (element.isTransient()) result.append(" transient=\"yes\""); |
753 | 4 | if (element.isSynthetic()) result.append(" synthetic=\"yes\""); |
754 | 4 | if (element.isDeprecated()) result.append(" deprecated=\"yes\""); |
755 | ||
756 | 4 | result.append(" type=\"").append(element.getType()).append("\""); |
757 | 4 | result.append(" name=\"").append(element.getName()).append("\""); |
758 | 4 | result.append(" signature=\"").append(element.getSignature()).append("\""); |
759 | 4 | result.append(" full-signature=\"").append(element.getFullSignature()).append("\""); |
760 | ||
761 | 4 | if (element.getConstantValue() != null) { |
762 | 2 | result.append(" value=\"").append(element.getConstantValue().getRawValue()).append("\""); |
763 | } | |
764 | } | |
765 | ||
766 | 4 | return result.toString(); |
767 | } | |
768 | ||
769 | private String breakdownDeclaration(Method_info element) { | |
770 | 25 | StringBuffer result = new StringBuffer(); |
771 | ||
772 | 25 | if (element != null) { |
773 | 25 | if (element.isPublic()) result.append(" visibility=\"public\""); |
774 | 25 | if (element.isProtected()) result.append(" visibility=\"protected\""); |
775 | 25 | if (element.isPackage()) result.append(" visibility=\"package\""); |
776 | 25 | if (element.isPrivate()) result.append(" visibility=\"private\""); |
777 | 25 | if (element.isStatic()) result.append(" static=\"yes\""); |
778 | 25 | if (element.isFinal()) result.append(" final=\"yes\""); |
779 | 25 | if (element.isSynchronized()) result.append(" synchronized=\"yes\""); |
780 | 25 | if (element.isNative()) result.append(" native=\"yes\""); |
781 | 25 | if (element.isAbstract()) result.append(" abstract=\"yes\""); |
782 | 25 | if (element.isStrict()) result.append(" strict=\"yes\""); |
783 | 25 | if (element.isSynthetic()) result.append(" synthetic=\"yes\""); |
784 | 25 | if (element.isDeprecated()) result.append(" deprecated=\"yes\""); |
785 | ||
786 | 25 | if (!element.getName().equals("<init>") && !element.getName().equals("<clinit>")) { |
787 | 18 | result.append(" return-type=\"").append(element.getReturnType()).append("\""); |
788 | } | |
789 | ||
790 | 25 | result.append(" signature=\"").append(element.getSignature()).append("\""); |
791 | 25 | result.append(" full-signature=\"").append(element.getFullSignature()).append("\""); |
792 | ||
793 | 25 | result.append(" throws=\""); |
794 | 25 | Iterator i = element.getExceptions().iterator(); |
795 | 25 | while (i.hasNext()) { |
796 | 0 | result.append(i.next()); |
797 | 0 | if (i.hasNext()) { |
798 | 0 | result.append(", "); |
799 | } | |
800 | } | |
801 | 25 | result.append("\""); |
802 | } | |
803 | ||
804 | 25 | return result.toString(); |
805 | } | |
806 | ||
807 | public int compareTo(Object other) { | |
808 | int result; | |
809 | ||
810 | 4 | if (other instanceof ClassReport) { |
811 | 4 | result = differences.compareTo(((ClassReport) other).differences); |
812 | } else { | |
813 | 0 | throw new ClassCastException("Unable to compare ClassReport to " + other.getClass().getName()); |
814 | } | |
815 | ||
816 | 4 | return result; |
817 | } | |
818 | ||
819 | private String escapeXMLCharactersInTagContent(String text) { | |
820 | 64 | String result = text; |
821 | ||
822 | 64 | result = perl.substitute("s/&/&/g", result); |
823 | 64 | result = perl.substitute("s/</</g", result); |
824 | 64 | result = perl.substitute("s/>/>/g", result); |
825 | ||
826 | 64 | return result; |
827 | } | |
828 | ||
829 | private String escapeXMLCharactersInAttributeValue(String text) { | |
830 | 36 | String result = escapeXMLCharactersInTagContent(text); |
831 | ||
832 | 36 | result = perl.substitute("s/\"/"/g", result); |
833 | 36 | result = perl.substitute("s/'/'/g", result); |
834 | ||
835 | 36 | return result; |
836 | } | |
837 | } |