KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > com > jeantessier > diff > DifferencesFactory


1 /*
2  * Copyright (c) 2001-2005, 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.log4j.*;
38
39 import com.jeantessier.classreader.*;
40 import com.jeantessier.dependency.*;
41
42 public class DifferencesFactory {
43     private Validator oldValidator;
44     private Validator newValidator;
45
46     private ClassfileLoader oldJar;
47     private ClassfileLoader newJar;
48     private Classfile oldClass;
49     private Classfile newClass;
50
51     public DifferencesFactory(Validator oldValidator, Validator newValidator) {
52         this.oldValidator = oldValidator;
53         this.newValidator = newValidator;
54     }
55
56     public Differences createJarDifferences(String JavaDoc name, String JavaDoc oldVersion, ClassfileLoader oldJar, String JavaDoc newVersion, ClassfileLoader newJar) {
57         Logger.getLogger(getClass()).debug("Begin " + name + " (" + oldVersion + " -> " + newVersion + ")");
58
59         JarDifferences jarDifferences = new JarDifferences(name, oldVersion, newVersion);
60         Differences result = jarDifferences;
61         
62         this.oldJar = oldJar;
63         this.newJar = newJar;
64         
65         Logger.getLogger(getClass()).debug(" Collecting packages ...");
66         
67         Iterator i;
68
69         NodeFactory oldFactory = new NodeFactory();
70         i = oldJar.getAllClassfiles().iterator();
71         while (i.hasNext()) {
72             oldFactory.createClass(i.next().toString());
73         }
74
75         NodeFactory newFactory = new NodeFactory();
76         i = newJar.getAllClassfiles().iterator();
77         while (i.hasNext()) {
78             newFactory.createClass(i.next().toString());
79         }
80         
81         Collection packageLevel = new TreeSet();
82         packageLevel.addAll(oldFactory.getPackages().keySet());
83         packageLevel.addAll(newFactory.getPackages().keySet());
84         
85         Logger.getLogger(getClass()).debug(" Diff'ing packages ...");
86         
87         i = packageLevel.iterator();
88         while (i.hasNext()) {
89             String JavaDoc packageName = (String JavaDoc) i.next();
90             
91             PackageNode oldPackage = (PackageNode) oldFactory.getPackages().get(packageName);
92             PackageNode newPackage = (PackageNode) newFactory.getPackages().get(packageName);
93             
94             Differences differences = createPackageDifferences(packageName, oldPackage, newPackage);
95             if (!differences.isEmpty()) {
96                 jarDifferences.getPackageDifferences().add(differences);
97             }
98         }
99         
100         Logger.getLogger(getClass()).debug("End " + name + " (" + oldVersion + " -> " + newVersion + "): " + (result.isEmpty() ? "empty" : "not empty"));
101         
102         return result;
103     }
104     
105     public Differences createPackageDifferences(String JavaDoc name, PackageNode oldPackage, PackageNode newPackage) {
106         Logger.getLogger(getClass()).debug("Begin " + name);
107         
108         PackageDifferences packageDifferences = new PackageDifferences(name, oldPackage, newPackage);
109         Differences result = packageDifferences;
110         
111         if (oldPackage != null && newPackage != null) {
112             
113             Collection classLevel = new TreeSet();
114             Iterator i;
115             
116             i = oldPackage.getClasses().iterator();
117             while (i.hasNext()) {
118                 classLevel.add(i.next().toString());
119             }
120             
121             i = newPackage.getClasses().iterator();
122             while (i.hasNext()) {
123                 classLevel.add(i.next().toString());
124             }
125             
126             Logger.getLogger(getClass()).debug(" Diff'ing classes ...");
127             
128             i = classLevel.iterator();
129             while (i.hasNext()) {
130                 String JavaDoc className = (String JavaDoc) i.next();
131                 
132                 Classfile oldClass = oldJar.getClassfile(className);
133                 Classfile newClass = newJar.getClassfile(className);
134                 
135                 Differences differences = createClassDifferences(className, oldClass, newClass);
136                 if (!differences.isEmpty()) {
137                     packageDifferences.getClassDifferences().add(differences);
138                 }
139             }
140             
141             Logger.getLogger(getClass()).debug(" " + name + " has " + packageDifferences.getClassDifferences().size() + " class(es) that changed.");
142             
143             if (oldValidator.isAllowed(name) != newValidator.isAllowed(name)) {
144                 result = new DocumentableDifferences(result, oldValidator, newValidator);
145             }
146         }
147         
148         Logger.getLogger(getClass()).debug("End " + name + ": " + (result.isEmpty() ? "empty" : "not empty"));
149         
150         return result;
151     }
152     
153     public Differences createClassDifferences(String JavaDoc name, Classfile oldClass, Classfile newClass) {
154         Logger.getLogger(getClass()).debug("Begin " + name);
155
156         ClassDifferences classDifferences;
157         if (((oldClass != null) && oldClass.isInterface()) || ((newClass != null) && newClass.isInterface())) {
158             classDifferences = new InterfaceDifferences(name, oldClass, newClass);
159         } else {
160             classDifferences = new ClassDifferences(name, oldClass, newClass);
161         }
162         Differences result = classDifferences;
163
164         this.oldClass = oldClass;
165         this.newClass = newClass;
166         
167         if (oldClass != null && newClass != null) {
168             Logger.getLogger(getClass()).debug(" Collecting fields ...");
169             
170             Map fieldLevel = new TreeMap();
171             Iterator i;
172             
173             i = oldClass.getAllFields().iterator();
174             while (i.hasNext()) {
175                 Field_info field = (Field_info) i.next();
176                 fieldLevel.put(field.getName(), field.getFullSignature());
177             }
178             
179             i = newClass.getAllFields().iterator();
180             while (i.hasNext()) {
181                 Field_info field = (Field_info) i.next();
182                 fieldLevel.put(field.getName(), field.getFullSignature());
183             }
184             
185             Logger.getLogger(getClass()).debug(" Diff'ing fields ...");
186             
187             i = fieldLevel.keySet().iterator();
188             while (i.hasNext()) {
189                 String JavaDoc fieldName = (String JavaDoc) i.next();
190                 String JavaDoc fieldFullName = (String JavaDoc) fieldLevel.get(fieldName);
191                 
192                 Field_info oldField = oldClass.getField(fieldName);
193                 Field_info newField = newClass.getField(fieldName);
194                 
195                 Differences differences = createFeatureDifferences(fieldFullName, oldField, newField);
196                 if (!differences.isEmpty()) {
197                     classDifferences.getFeatureDifferences().add(differences);
198                 }
199             }
200             
201             Logger.getLogger(getClass()).debug(" Collecting methods ...");
202             
203             Map methodLevel = new TreeMap();
204             
205             i = oldClass.getAllMethods().iterator();
206             while (i.hasNext()) {
207                 Method_info method = (Method_info) i.next();
208                 methodLevel.put(method.getSignature(), method.getFullSignature());
209             }
210             
211             i = newClass.getAllMethods().iterator();
212             while (i.hasNext()) {
213                 Method_info method = (Method_info) i.next();
214                 methodLevel.put(method.getSignature(), method.getFullSignature());
215             }
216             
217             Logger.getLogger(getClass()).debug(" Diff'ing methods ...");
218             
219             i = methodLevel.keySet().iterator();
220             while (i.hasNext()) {
221                 String JavaDoc methodName = (String JavaDoc) i.next();
222                 String JavaDoc methodFullName = (String JavaDoc) methodLevel.get(methodName);
223                 
224                 Method_info oldMethod = oldClass.getMethod(methodName);
225                 Method_info newMethod = newClass.getMethod(methodName);
226                 
227                 Differences differences = createFeatureDifferences(methodFullName, oldMethod, newMethod);
228                 if (!differences.isEmpty()) {
229                     classDifferences.getFeatureDifferences().add(differences);
230                 }
231             }
232             
233             Logger.getLogger(getClass()).debug(name + " has " + classDifferences.getFeatureDifferences().size() + " feature(s) that changed.");
234
235             if (oldClass.isDeprecated() != newClass.isDeprecated()) {
236                 result = new DeprecatableDifferences(result, oldClass, newClass);
237             }
238             
239             if (oldValidator.isAllowed(name) != newValidator.isAllowed(name)) {
240                 result = new DocumentableDifferences(result, oldValidator, newValidator);
241             }
242         }
243
244         Logger.getLogger(getClass()).debug("End " + name + ": " + (result.isEmpty() ? "empty" : "not empty"));
245
246         return result;
247     }
248
249     public Differences createFeatureDifferences(String JavaDoc name, Feature_info oldFeature, Feature_info newFeature) {
250         Logger.getLogger(getClass()).debug("Begin " + name);
251
252         FeatureDifferences featureDifferences;
253         if (oldFeature instanceof Field_info || newFeature instanceof Field_info) {
254             featureDifferences = new FieldDifferences(name, oldFeature, newFeature);
255
256             if (featureDifferences.isRemoved() && newClass.locateField(name) != null) {
257                 featureDifferences.setInherited(true);
258             }
259         } else {
260             if (((oldFeature instanceof Method_info) && ((Method_info) oldFeature).isConstructor()) || ((newFeature instanceof Method_info) && ((Method_info) newFeature).isConstructor())) {
261                 featureDifferences = new ConstructorDifferences(name, oldFeature, newFeature);
262             } else {
263                 featureDifferences = new MethodDifferences(name, oldFeature, newFeature);
264             }
265
266             if (featureDifferences.isRemoved()) {
267                 Method_info attempt = newClass.locateMethod(name);
268                 if ((attempt != null) && (oldFeature.getClassfile().isInterface() == attempt.getClassfile().isInterface())) {
269                     featureDifferences.setInherited(true);
270                 }
271             }
272         }
273         Differences result = featureDifferences;
274         
275         if (oldFeature != null && newFeature != null) {
276             if (oldFeature.isDeprecated() != newFeature.isDeprecated()) {
277                 result = new DeprecatableDifferences(result, oldFeature, newFeature);
278             }
279
280             if (oldValidator.isAllowed(name) != newValidator.isAllowed(name)) {
281                 result = new DocumentableDifferences(result, oldValidator, newValidator);
282             }
283         }
284
285         Logger.getLogger(getClass()).debug("End " + name + ": " + (result.isEmpty() ? "empty" : "not empty"));
286
287         return result;
288     }
289 }
290
Popular Tags