KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > clirr > cli > Clirr


1 //////////////////////////////////////////////////////////////////////////////
2
// Clirr: compares two versions of a java library for binary compatibility
3
// Copyright (C) 2003 - 2005 Lars Kühne
4
//
5
// This library is free software; you can redistribute it and/or
6
// modify it under the terms of the GNU Lesser General Public
7
// License as published by the Free Software Foundation; either
8
// version 2.1 of the License, or (at your option) any later version.
9
//
10
// This library is distributed in the hope that it will be useful,
11
// but WITHOUT ANY WARRANTY; without even the implied warranty of
12
// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13
// Lesser General Public License for more details.
14
//
15
// You should have received a copy of the GNU Lesser General Public
16
// License along with this library; if not, write to the Free Software
17
// Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
18
//////////////////////////////////////////////////////////////////////////////
19

20 package net.sf.clirr.cli;
21
22 import net.sf.clirr.core.Checker;
23 import net.sf.clirr.core.CheckerException;
24 import net.sf.clirr.core.ClassSelector;
25 import net.sf.clirr.core.PlainDiffListener;
26 import net.sf.clirr.core.XmlDiffListener;
27 import net.sf.clirr.core.DiffListener;
28 import net.sf.clirr.core.internal.bcel.BcelTypeArrayBuilder;
29 import net.sf.clirr.core.spi.JavaType;
30 import net.sf.clirr.core.spi.Scope;
31
32 import org.apache.commons.cli.BasicParser;
33 import org.apache.commons.cli.CommandLine;
34 import org.apache.commons.cli.HelpFormatter;
35 import org.apache.commons.cli.Options;
36 import org.apache.commons.cli.ParseException;
37
38 import java.io.File JavaDoc;
39 import java.io.IOException JavaDoc;
40 import java.io.PrintWriter JavaDoc;
41 import java.net.MalformedURLException JavaDoc;
42 import java.net.URL JavaDoc;
43 import java.net.URLClassLoader JavaDoc;
44 import java.util.ArrayList JavaDoc;
45
46 /**
47  * Commandline interface for generating a difference report or checking
48  * for binary compatibility between two versions of the same application.
49  */

50
51 public class Clirr
52 {
53
54     public static void main(String JavaDoc[] args)
55     {
56         new Clirr().run(args);
57     }
58
59     // ===================================================================
60

61     private void run(String JavaDoc[] args)
62     {
63         Options options = defineOptions();
64
65         CommandLine cmdline = parseCommandLine(args, options);
66
67         String JavaDoc oldPath = cmdline.getOptionValue('o');
68         String JavaDoc newPath = cmdline.getOptionValue('n');
69         String JavaDoc oldClassPath = cmdline.getOptionValue("ocp");
70         String JavaDoc newClassPath = cmdline.getOptionValue("ncp");
71         String JavaDoc style = cmdline.getOptionValue('s', "text");
72         String JavaDoc outputFileName = cmdline.getOptionValue('f');
73         String JavaDoc[] includePkgs = cmdline.getOptionValues('i');
74         boolean showAll = cmdline.hasOption('a');
75         boolean showPkg = cmdline.hasOption('p');
76
77         if ((oldPath == null) || (newPath == null))
78         {
79             usage(options);
80             System.exit(-1);
81         }
82
83         Checker checker = new Checker();
84         if (showAll)
85         {
86             checker.getScopeSelector().setScope(Scope.PRIVATE);
87         }
88         else if (showPkg)
89         {
90             checker.getScopeSelector().setScope(Scope.PACKAGE);
91         }
92
93         ClassSelector classSelector;
94         if ((includePkgs != null) && (includePkgs.length > 0))
95         {
96             classSelector = new ClassSelector(ClassSelector.MODE_IF);
97             for (int i = 0; i < includePkgs.length; ++i)
98             {
99                 classSelector.addPackageTree(includePkgs[i]);
100             }
101         }
102         else
103         {
104             // a selector that selects everything
105
classSelector = new ClassSelector(ClassSelector.MODE_UNLESS);
106         }
107
108         DiffListener diffListener = null;
109         if (style.equals("text"))
110         {
111             try
112             {
113                 diffListener = new PlainDiffListener(outputFileName);
114             }
115             catch (IOException JavaDoc ex)
116             {
117                 System.err.println("Invalid output file name.");
118             }
119         }
120         else if (style.equals("xml"))
121         {
122             try
123             {
124                 diffListener = new XmlDiffListener(outputFileName);
125             }
126             catch (IOException JavaDoc ex)
127             {
128                 System.err.println("Invalid output file name.");
129             }
130         }
131         else
132         {
133             System.err.println("Invalid style option. Must be one of 'text', 'xml'.");
134             usage(options);
135             System.exit(-1);
136         }
137
138
139         File JavaDoc[] origJars = pathToFileArray(oldPath);
140         File JavaDoc[] newJars = pathToFileArray(newPath);
141
142         checker.addDiffListener(diffListener);
143
144         try
145         {
146             ClassLoader JavaDoc loader1 = new URLClassLoader JavaDoc(convertFilesToURLs(pathToFileArray(oldClassPath)));
147             ClassLoader JavaDoc loader2 = new URLClassLoader JavaDoc(convertFilesToURLs(pathToFileArray(newClassPath)));
148
149             final JavaType[] origClasses =
150                 BcelTypeArrayBuilder.createClassSet(origJars, loader1, classSelector);
151             
152             final JavaType[] newClasses =
153                 BcelTypeArrayBuilder.createClassSet(newJars, loader2, classSelector);
154             
155             checker.reportDiffs(origClasses, newClasses);
156             
157             System.exit(0);
158         }
159         catch (CheckerException ex)
160         {
161             System.err.println("Unable to complete checks:" + ex.getMessage());
162             System.exit(1);
163         }
164         catch (MalformedURLException JavaDoc ex)
165         {
166             System.err.println("Unable to create classloader for 3rd party classes:" + ex.getMessage());
167             System.err.println("old classpath: " + oldClassPath);
168             System.err.println("new classpath: " + newClassPath);
169             System.exit(1);
170         }
171     }
172
173     /**
174      * @param args
175      * @param parser
176      * @param options
177      * @return
178      */

179     private CommandLine parseCommandLine(String JavaDoc[] args, Options options)
180     {
181         BasicParser parser = new BasicParser();
182         CommandLine cmdline = null;
183         try
184         {
185             cmdline = parser.parse(options, args);
186         }
187         catch (ParseException ex)
188         {
189             System.err.println("Invalid command line arguments.");
190             usage(options);
191             System.exit(-1);
192         }
193         return cmdline;
194     }
195
196     /**
197      * @return
198      */

199     private Options defineOptions() {
200         Options options = new Options();
201         options.addOption("o", "old-version", true, "jar files of old version");
202         options.addOption("n", "new-version", true, "jar files of new version");
203         options.addOption("ocp", "orig-classpath", true, "3rd party classpath that is referenced by old-version");
204         options.addOption("ncp", "new-classpath", true, "3rd party classpath that is referenced by new-version");
205         options.addOption("s", "style", true, "output style [text|xml]");
206         options.addOption("i", "include-pkg", true,
207             "include only classes from this package and its subpackages");
208         options.addOption("p", "show-pkg-scope", false,
209             "show package scope classes");
210         options.addOption("a", "show-all-scopes", false,
211             "show private and package classes");
212         options.addOption("f", "output-file", true, "output file name");
213         return options;
214     }
215
216     private void usage(Options options)
217     {
218         HelpFormatter hf = new HelpFormatter();
219         PrintWriter JavaDoc out = new PrintWriter JavaDoc(System.err);
220         hf.printHelp(
221             75,
222             "java " + getClass().getName() + " -o path -n path [options]",
223             null, options, null);
224     }
225
226     private File JavaDoc[] pathToFileArray(String JavaDoc path)
227     {
228         if (path == null)
229         {
230             return new File JavaDoc[0];
231         }
232         
233         ArrayList JavaDoc files = new ArrayList JavaDoc();
234
235         int pos = 0;
236         while (pos < path.length())
237         {
238             int colonPos = path.indexOf(pos, File.pathSeparatorChar);
239             if (colonPos == -1)
240             {
241                 files.add(new File JavaDoc(path.substring(pos)));
242                 break;
243             }
244
245             files.add(new File JavaDoc(path.substring(pos, colonPos)));
246             pos = colonPos + 1;
247         }
248
249         return (File JavaDoc[]) files.toArray(new File JavaDoc[files.size()]);
250     }
251     
252     private URL JavaDoc[] convertFilesToURLs(File JavaDoc[] files) throws MalformedURLException JavaDoc
253     {
254         URL JavaDoc[] ret = new URL JavaDoc[files.length];
255         for (int i = 0; i < files.length; i++) {
256             ret[i] = files[i].toURL();
257         }
258         return ret;
259     }
260 }
261
Popular Tags