001: /*
002: * Copyright (c) 2001-2007, Jean Tessier
003: * All rights reserved.
004: *
005: * Redistribution and use in source and binary forms, with or without
006: * modification, are permitted provided that the following conditions
007: * are met:
008: *
009: * * Redistributions of source code must retain the above copyright
010: * notice, this list of conditions and the following disclaimer.
011: *
012: * * Redistributions in binary form must reproduce the above copyright
013: * notice, this list of conditions and the following disclaimer in the
014: * documentation and/or other materials provided with the distribution.
015: *
016: * * Neither the name of Jean Tessier nor the names of his contributors
017: * may be used to endorse or promote products derived from this software
018: * without specific prior written permission.
019: *
020: * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
021: * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
022: * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
023: * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR
024: * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
025: * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
026: * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
027: * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF
028: * LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
029: * NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS
030: * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
031: */
032:
033: package com.jeantessier.diff;
034:
035: import java.util.*;
036:
037: import com.jeantessier.classreader.*;
038:
039: public class Report extends Printer {
040: public static final String DEFAULT_ENCODING = "utf-8";
041: public static final String DEFAULT_DTD_PREFIX = "http://depfind.sourceforge.net/dtd";
042:
043: private String name;
044: private String oldVersion;
045: private String newVersion;
046:
047: private Collection<Differences> removedPackages = new TreeSet<Differences>();
048:
049: private Collection<ClassDifferences> removedInterfaces = new TreeSet<ClassDifferences>();
050: private Collection<ClassDifferences> removedClasses = new TreeSet<ClassDifferences>();
051:
052: private Collection<ClassDifferences> deprecatedInterfaces = new TreeSet<ClassDifferences>();
053: private Collection<ClassDifferences> deprecatedClasses = new TreeSet<ClassDifferences>();
054:
055: private Collection<ClassReport> modifiedInterfaces = new TreeSet<ClassReport>();
056: private Collection<ClassReport> modifiedClasses = new TreeSet<ClassReport>();
057:
058: private Collection<ClassDifferences> undeprecatedInterfaces = new TreeSet<ClassDifferences>();
059: private Collection<ClassDifferences> undeprecatedClasses = new TreeSet<ClassDifferences>();
060:
061: private Collection<Differences> newPackages = new TreeSet<Differences>();
062:
063: private Collection<ClassDifferences> newInterfaces = new TreeSet<ClassDifferences>();
064: private Collection<ClassDifferences> newClasses = new TreeSet<ClassDifferences>();
065:
066: public Report() {
067: this (DEFAULT_ENCODING, DEFAULT_DTD_PREFIX);
068: }
069:
070: public Report(String encoding, String dtdPrefix) {
071: appendHeader(encoding, dtdPrefix);
072: }
073:
074: public void setName(String name) {
075: this .name = name;
076: }
077:
078: public void setOldVersion(String oldVersion) {
079: this .oldVersion = oldVersion;
080: }
081:
082: public void setNewVersion(String newVersion) {
083: this .newVersion = newVersion;
084: }
085:
086: private void appendHeader(String encoding, String dtdPrefix) {
087: append("<?xml version=\"1.0\" encoding=\"").append(encoding)
088: .append("\" ?>").eol();
089: eol();
090: append("<!DOCTYPE differences SYSTEM \"").append(dtdPrefix)
091: .append("/differences.dtd\">").eol();
092: eol();
093: }
094:
095: public void visitProjectDifferences(ProjectDifferences differences) {
096: setName(differences.getName());
097: setOldVersion(differences.getOldVersion());
098: setNewVersion(differences.getNewVersion());
099:
100: for (Differences packageDifference : differences
101: .getPackageDifferences()) {
102: packageDifference.accept(this );
103: }
104: }
105:
106: public void visitPackageDifferences(PackageDifferences differences) {
107: if (differences.isRemoved()) {
108: removedPackages.add(differences);
109: }
110:
111: for (Differences classDiffenrence : differences
112: .getClassDifferences()) {
113: classDiffenrence.accept(this );
114: }
115:
116: if (differences.isNew()) {
117: newPackages.add(differences);
118: }
119: }
120:
121: public void visitClassDifferences(ClassDifferences differences) {
122: if (differences.isRemoved()) {
123: removedClasses.add(differences);
124: }
125:
126: if (differences.isModified()) {
127: ClassReport visitor = new ClassReport();
128: visitor.setIndentText(getIndentText());
129: differences.accept(visitor);
130: modifiedClasses.add(visitor);
131: }
132:
133: if (differences.isNew()) {
134: newClasses.add(differences);
135: }
136:
137: if (isDeprecated()) {
138: deprecatedClasses.add(differences);
139: }
140:
141: if (isUndeprecated()) {
142: undeprecatedClasses.add(differences);
143: }
144: }
145:
146: public void visitInterfaceDifferences(
147: InterfaceDifferences differences) {
148: if (differences.isRemoved()) {
149: removedInterfaces.add(differences);
150: }
151:
152: if (differences.isModified()) {
153: ClassReport classReport = new ClassReport();
154: classReport.setIndentText(getIndentText());
155: differences.accept(classReport);
156: modifiedInterfaces.add(classReport);
157: }
158:
159: if (differences.isNew()) {
160: newInterfaces.add(differences);
161: }
162:
163: if (isDeprecated()) {
164: deprecatedInterfaces.add(differences);
165: }
166:
167: if (isUndeprecated()) {
168: undeprecatedInterfaces.add(differences);
169: }
170: }
171:
172: public String toString() {
173: indent().append("<differences>").eol();
174: raiseIndent();
175:
176: indent().append("<name>").append(name).append("</name>").eol();
177: indent().append("<old>").append(oldVersion).append("</old>")
178: .eol();
179: indent().append("<new>").append(newVersion).append("</new>")
180: .eol();
181:
182: if (removedPackages.size() != 0) {
183: indent().append("<removed-packages>").eol();
184: raiseIndent();
185:
186: for (Differences removedPackage : removedPackages) {
187: indent().append("<name>").append(removedPackage)
188: .append("</name>").eol();
189: }
190:
191: lowerIndent();
192: indent().append("</removed-packages>").eol();
193: }
194:
195: if (removedInterfaces.size() != 0) {
196: indent().append("<removed-interfaces>").eol();
197: raiseIndent();
198:
199: for (ClassDifferences cd : removedInterfaces) {
200: indent().append("<name").append(
201: breakdownDeclaration(cd.getOldClass())).append(
202: ">").append(cd).append("</name>").eol();
203: }
204:
205: lowerIndent();
206: indent().append("</removed-interfaces>").eol();
207: }
208:
209: if (removedClasses.size() != 0) {
210: indent().append("<removed-classes>").eol();
211: raiseIndent();
212:
213: for (ClassDifferences cd : removedClasses) {
214: indent().append("<name").append(
215: breakdownDeclaration(cd.getOldClass())).append(
216: ">").append(cd).append("</name>").eol();
217: }
218:
219: lowerIndent();
220: indent().append("</removed-classes>").eol();
221: }
222:
223: if (deprecatedInterfaces.size() != 0) {
224: indent().append("<deprecated-interfaces>").eol();
225: raiseIndent();
226:
227: for (ClassDifferences cd : deprecatedInterfaces) {
228: indent().append("<name").append(
229: breakdownDeclaration(cd.getNewClass())).append(
230: ">").append(cd).append("</name>").eol();
231: }
232:
233: lowerIndent();
234: indent().append("</deprecated-interfaces>").eol();
235: }
236:
237: if (deprecatedClasses.size() != 0) {
238: indent().append("<deprecated-classes>").eol();
239: raiseIndent();
240:
241: for (ClassDifferences cd : deprecatedClasses) {
242: indent().append("<name").append(
243: breakdownDeclaration(cd.getNewClass())).append(
244: ">").append(cd).append("</name>").eol();
245: }
246:
247: lowerIndent();
248: indent().append("</deprecated-classes>").eol();
249: }
250:
251: if (modifiedInterfaces.size() != 0) {
252: indent().append("<modified-interfaces>").eol();
253: raiseIndent();
254:
255: for (ClassReport modifiedInterface : modifiedInterfaces) {
256: append(modifiedInterface);
257: }
258:
259: lowerIndent();
260: indent().append("</modified-interfaces>").eol();
261: }
262:
263: if (modifiedClasses.size() != 0) {
264: indent().append("<modified-classes>").eol();
265: raiseIndent();
266:
267: for (ClassReport modifiedClass : modifiedClasses) {
268: append(modifiedClass);
269: }
270:
271: lowerIndent();
272: indent().append("</modified-classes>").eol();
273: }
274:
275: if (undeprecatedInterfaces.size() != 0) {
276: indent().append("<undeprecated-interfaces>").eol();
277: raiseIndent();
278:
279: for (ClassDifferences cd : undeprecatedInterfaces) {
280: indent().append("<name").append(
281: breakdownDeclaration(cd.getNewClass())).append(
282: ">").append(cd).append("</name>").eol();
283: }
284:
285: lowerIndent();
286: indent().append("</undeprecated-interfaces>").eol();
287: }
288:
289: if (undeprecatedClasses.size() != 0) {
290: indent().append("<undeprecated-classes>").eol();
291: raiseIndent();
292:
293: for (ClassDifferences cd : undeprecatedClasses) {
294: indent().append("<name").append(
295: breakdownDeclaration(cd.getNewClass())).append(
296: ">").append(cd).append("</name>").eol();
297: }
298:
299: lowerIndent();
300: indent().append("</undeprecated-classes>").eol();
301: }
302:
303: if (newPackages.size() != 0) {
304: indent().append("<new-packages>").eol();
305: raiseIndent();
306:
307: for (Differences newPackage : newPackages) {
308: indent().append("<name>").append(newPackage).append(
309: "</name>").eol();
310: }
311:
312: lowerIndent();
313: indent().append("</new-packages>").eol();
314: }
315:
316: if (newInterfaces.size() != 0) {
317: indent().append("<new-interfaces>").eol();
318: raiseIndent();
319:
320: for (ClassDifferences cd : newInterfaces) {
321: indent().append("<name").append(
322: breakdownDeclaration(cd.getNewClass())).append(
323: ">").append(cd).append("</name>").eol();
324: }
325:
326: lowerIndent();
327: indent().append("</new-interfaces>").eol();
328: }
329:
330: if (newClasses.size() != 0) {
331: indent().append("<new-classes>").eol();
332: raiseIndent();
333:
334: for (ClassDifferences cd : newClasses) {
335: indent().append("<name").append(
336: breakdownDeclaration(cd.getNewClass())).append(
337: ">").append(cd).append("</name>").eol();
338: }
339:
340: lowerIndent();
341: indent().append("</new-classes>").eol();
342: }
343:
344: lowerIndent();
345: indent().append("</differences>").eol();
346:
347: return super .toString();
348: }
349:
350: private String breakdownDeclaration(Classfile element) {
351: StringBuffer result = new StringBuffer();
352:
353: if (element != null) {
354: if (element.isPublic())
355: result.append(" visibility=\"public\"");
356: if (element.isPackage())
357: result.append(" visibility=\"package\"");
358: if (element.isFinal())
359: result.append(" final=\"yes\"");
360: if (element.isSuper())
361: result.append(" super=\"yes\"");
362: if (element.isSynthetic())
363: result.append(" synthetic=\"yes\"");
364: if (element.isDeprecated())
365: result.append(" deprecated=\"yes\"");
366:
367: result.append(" name=\"").append(element.getClassName())
368: .append("\"");
369:
370: if (element.isInterface()) {
371: result.append(" interface=\"yes\"");
372:
373: result.append(" extends=\"");
374: Iterator i = element.getAllInterfaces().iterator();
375: while (i.hasNext()) {
376: result.append(i.next());
377: if (i.hasNext()) {
378: result.append(", ");
379: }
380: }
381: result.append("\"");
382: } else {
383: if (element.isAbstract())
384: result.append(" abstract=\"yes\"");
385:
386: result.append(" extends=\"").append(
387: element.getSuperclassName()).append("\"");
388:
389: result.append(" implements=\"");
390: Iterator i = element.getAllInterfaces().iterator();
391: while (i.hasNext()) {
392: result.append(i.next());
393: if (i.hasNext()) {
394: result.append(", ");
395: }
396: }
397: result.append("\"");
398: }
399: }
400:
401: return result.toString();
402: }
403: }
|