KickJava   Java API By Example, From Geeks To Geeks.

Java > Open Source Codes > net > sf > retrotranslator > transformer > Retrotranslator


1 /***
2  * Retrotranslator: a Java bytecode transformer that translates Java classes
3  * compiled with JDK 5.0 into classes that can be run on JVM 1.4.
4  *
5  * Copyright (c) 2005 - 2007 Taras Puchko
6  * All rights reserved.
7  *
8  * Redistribution and use in source and binary forms, with or without
9  * modification, are permitted provided that the following conditions
10  * are met:
11  * 1. Redistributions of source code must retain the above copyright
12  * notice, this list of conditions and the following disclaimer.
13  * 2. Redistributions in binary form must reproduce the above copyright
14  * notice, this list of conditions and the following disclaimer in the
15  * documentation and/or other materials provided with the distribution.
16  * 3. Neither the name of the copyright holders nor the names of its
17  * contributors may be used to endorse or promote products derived from
18  * this software without specific prior written permission.
19  *
20  * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
21  * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
22  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
23  * ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
24  * LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
25  * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
26  * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
27  * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
28  * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
29  * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF
30  * THE POSSIBILITY OF SUCH DAMAGE.
31  */

32 package net.sf.retrotranslator.transformer;
33
34 import java.io.File JavaDoc;
35 import java.util.*;
36
37 /**
38  * @author Taras Puchko
39  */

40 public class Retrotranslator implements MessageLogger {
41
42     private LinkedList<FileContainer> src = new LinkedList<FileContainer>();
43     private FileContainer dest;
44     private boolean stripsign;
45     private boolean retainapi;
46     private boolean retainflags;
47     private boolean verbose;
48     private boolean lazy;
49     private boolean advanced;
50     private boolean verify;
51     private List<File JavaDoc> classpath = new ArrayList<File JavaDoc>();
52     private MessageLogger logger = this;
53     private SourceMask sourceMask = new SourceMask(null);
54     private String JavaDoc embed;
55     private List<Backport> backports = new ArrayList<Backport>();
56     private ClassVersion target = ClassVersion.VERSION_14;
57     private ClassLoader JavaDoc classLoader;
58
59     public Retrotranslator() {
60     }
61
62     public void addSrcdir(File JavaDoc srcdir) {
63         if (!srcdir.isDirectory()) throw new IllegalArgumentException JavaDoc("Invalid srcdir: " + srcdir);
64         src.add(new FolderFileContainer(srcdir));
65     }
66
67     public void addSrcjar(File JavaDoc srcjar) {
68         if (!srcjar.isFile()) throw new IllegalArgumentException JavaDoc("Invalid srcjar: " + srcjar);
69         src.add(new JarFileContainer(srcjar));
70     }
71
72     public void addSourceFiles(File JavaDoc srcdir, List<String JavaDoc> fileNames) {
73         if (!srcdir.isDirectory()) throw new IllegalArgumentException JavaDoc("Invalid srcdir: " + srcdir);
74         src.add(new FolderFileContainer(srcdir, fileNames));
75     }
76
77     public void setDestdir(File JavaDoc destdir) {
78         if (!destdir.isDirectory()) throw new IllegalArgumentException JavaDoc("Invalid destdir: " + destdir);
79         if (dest != null) throw new IllegalArgumentException JavaDoc("Destination already set.");
80         dest = new FolderFileContainer(destdir);
81     }
82
83     public void setDestjar(File JavaDoc destjar) {
84         if (destjar.isDirectory()) throw new IllegalArgumentException JavaDoc("Invalid destjar: " + destjar);
85         if (dest != null) throw new IllegalArgumentException JavaDoc("Destination already set.");
86         dest = new JarFileContainer(destjar);
87     }
88
89     public void setStripsign(boolean stripsign) {
90         this.stripsign = stripsign;
91     }
92
93     public void setRetainapi(boolean retainapi) {
94         this.retainapi = retainapi;
95     }
96
97     public void setRetainflags(boolean retainflags) {
98         this.retainflags = retainflags;
99     }
100
101     public void setVerbose(boolean verbose) {
102         this.verbose = verbose;
103     }
104
105     public void setLazy(boolean lazy) {
106         this.lazy = lazy;
107     }
108
109     public void setAdvanced(boolean advanced) {
110         this.advanced = advanced;
111     }
112
113     public void setVerify(boolean verify) {
114         this.verify = verify;
115     }
116
117     public void addClasspathElement(File JavaDoc classpathElement) {
118         this.classpath.add(classpathElement);
119     }
120
121     public void addClasspath(String JavaDoc classpath) {
122         StringTokenizer tokenizer = new StringTokenizer(classpath, File.pathSeparator);
123         while (tokenizer.hasMoreTokens()) {
124             addClasspathElement(new File JavaDoc(tokenizer.nextToken()));
125         }
126     }
127
128     public void setSrcmask(String JavaDoc srcmask) {
129         sourceMask = new SourceMask(srcmask);
130     }
131
132     public void setEmbed(String JavaDoc embed) {
133         this.embed = embed;
134     }
135
136     public void setBackport(String JavaDoc backport) {
137         backports = Backport.asList(backport);
138     }
139
140     public void setTarget(String JavaDoc target) {
141         this.target = ClassVersion.valueOf(target);
142     }
143
144     public void setLogger(MessageLogger logger) {
145         this.logger = logger;
146     }
147
148     public void setClassLoader(ClassLoader JavaDoc classLoader) {
149         this.classLoader = classLoader;
150     }
151
152     public void log(Message message) {
153         System.out.println(message);
154     }
155
156     public boolean run() {
157         if (src.isEmpty()) throw new IllegalArgumentException JavaDoc("Source not set.");
158         EmbeddingConverter converter = null;
159         if (embed != null) {
160             if (dest == null) throw new IllegalArgumentException JavaDoc("Destination required for embedding!");
161             if (lazy) throw new IllegalArgumentException JavaDoc("Embedding cannot be lazy!");
162             converter = new EmbeddingConverter(embed);
163         }
164         SystemLogger systemLogger = new SystemLogger(logger, verbose);
165         ReplacementLocatorFactory locatorFactory = new ReplacementLocatorFactory(target, advanced, retainapi, backports);
166         ClassTransformer classTransformer = new ClassTransformer(
167                 lazy, stripsign, retainflags, systemLogger, converter, locatorFactory);
168         TextFileTransformer fileTransformer = new TextFileTransformer(locatorFactory);
169         FileTranslator translator = new FileTranslator(
170                 classTransformer, fileTransformer, converter, systemLogger, sourceMask);
171         for (FileContainer container : src) {
172             translator.transform(container, dest != null ? dest : container);
173         }
174         if (converter != null) {
175             translator.embed(dest);
176         }
177         if (dest != null) dest.flush(systemLogger);
178         if (!verify) return true;
179         ClassLoader JavaDoc loader = classLoader;
180         if (loader == null && classpath.isEmpty()) {
181             loader = this.getClass().getClassLoader();
182         }
183         ClassReaderFactory factory = new ClassReaderFactory(loader);
184         try {
185             return verify(factory, systemLogger);
186         } finally {
187             factory.close();
188         }
189     }
190
191     private boolean verify(ClassReaderFactory factory, SystemLogger systemLogger) {
192         if (dest != null) {
193             factory.appendPath(dest.getLocation());
194         } else {
195             for (FileContainer container : src) {
196                 factory.appendPath(container.getLocation());
197             }
198         }
199         for (File JavaDoc file : classpath) {
200             factory.appendPath(file);
201         }
202         if (dest != null) {
203             verify(factory, dest, systemLogger);
204         } else {
205             for (FileContainer container : src) {
206                 verify(factory, container, systemLogger);
207             }
208         }
209         return systemLogger.isReliable();
210     }
211
212     private void verify(ClassReaderFactory factory, FileContainer container, SystemLogger systemLogger) {
213         systemLogger.log(new Message(Level.INFO,
214                 "Verifying " + container.getFileCount() + " file(s) in " + container + "."));
215         int warningCount = 0;
216         for (final FileEntry entry : container.getEntries()) {
217             if (sourceMask.matches(entry.getName())) {
218                 byte[] content = entry.getContent();
219                 if (TransformerTools.isClassFile(content)) {
220                     systemLogger.setFile(container.getLocation(), entry.getName());
221                     systemLogger.logForFile(Level.VERBOSE, "Verification");
222                     warningCount += new ReferenceVerifyingVisitor(factory, systemLogger).verify(content);
223                 }
224             }
225         }
226         String JavaDoc result = warningCount != 0 ? " with " + warningCount + " warning(s)." : " successfully.";
227         systemLogger.log(new Message(Level.INFO,
228                 "Verification of " + container.getFileCount() + " file(s) completed" + result));
229     }
230
231     private boolean execute(String JavaDoc[] args) {
232         int i = 0;
233         while (i < args.length) {
234             String JavaDoc string = args[i++];
235             if (string.equals("-srcdir") && i < args.length) {
236                 addSrcdir(new File JavaDoc(args[i++]));
237             } else if (string.equals("-srcjar") && i < args.length) {
238                 addSrcjar(new File JavaDoc(args[i++]));
239             } else if (string.equals("-destdir") && i < args.length) {
240                 setDestdir(new File JavaDoc(args[i++]));
241             } else if (string.equals("-destjar") && i < args.length) {
242                 setDestjar(new File JavaDoc(args[i++]));
243             } else if (string.equals("-stripsign")) {
244                 setStripsign(true);
245             } else if (string.equals("-retainapi")) {
246                 setRetainapi(true);
247             } else if (string.equals("-retainflags")) {
248                 setRetainflags(true);
249             } else if (string.equals("-verbose")) {
250                 setVerbose(true);
251             } else if (string.equals("-lazy")) {
252                 setLazy(true);
253             } else if (string.equals("-advanced")) {
254                 setAdvanced(true);
255             } else if (string.equals("-verify")) {
256                 setVerify(true);
257             } else if (string.equals("-classpath") && i < args.length) {
258                 addClasspath(args[i++]);
259             } else if (string.equals("-srcmask") && i < args.length) {
260                 setSrcmask(args[i++]);
261             } else if (string.equals("-embed") && i < args.length) {
262                 setEmbed(args[i++]);
263             } else if (string.equals("-backport") && i < args.length) {
264                 setBackport(args[i++]);
265             } else if (string.equals("-target") && i < args.length) {
266                 setTarget(args[i++]);
267             } else {
268                 throw new IllegalArgumentException JavaDoc("Unknown option: " + string);
269             }
270         }
271         return run();
272     }
273
274     private static void printUsage() {
275         String JavaDoc version = Retrotranslator.class.getPackage().getImplementationVersion();
276         String JavaDoc suffix = (version == null) ? "" : "-" + version;
277         System.out.println("Usage: java -jar retrotranslator-transformer" + suffix + ".jar" +
278                 " [-srcdir <path> | -srcjar <file>] [-destdir <path> | -destjar <file>] [-stripsign]" +
279                 " [-verbose] [-lazy] [-advanced] [-retainapi] [-retainflags] [-verify] [-target <version>]" +
280                 " [-classpath <classpath>] [-srcmask <mask>] [-embed <package>] [-backport <packages>]");
281     }
282
283     public static void main(String JavaDoc[] args) {
284         if (args.length == 0) {
285             printUsage();
286             return;
287         }
288         try {
289             if (!new Retrotranslator().execute(args)) {
290                 System.exit(2);
291             }
292         } catch (IllegalArgumentException JavaDoc e) {
293             System.out.println(e.getMessage());
294             printUsage();
295             System.exit(1);
296         }
297     }
298
299 }
300
Popular Tags