1 /*
2  * ProGuard -- shrinking, optimization, obfuscation, and preverification
3  *             of Java bytecode.
4  *
5  * Copyright (c) 2002-2014 Eric Lafortune (eric@graphics.cornell.edu)
6  *
7  * This program is free software; you can redistribute it and/or modify it
8  * under the terms of the GNU General Public License as published by the Free
9  * Software Foundation; either version 2 of the License, or (at your option)
10  * any later version.
11  *
12  * This program is distributed in the hope that it will be useful, but WITHOUT
13  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
14  * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for
15  * more details.
16  *
17  * You should have received a copy of the GNU General Public License along
18  * with this program; if not, write to the Free Software Foundation, Inc.,
19  * 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
20  */
21 package proguard.ant;
22 
23 import org.apache.tools.ant.BuildException;
24 import proguard.*;
25 import proguard.classfile.util.ClassUtil;
26 
27 import java.io.*;
28 import java.util.*;
29 
30 /**
31  * This Task allows to configure and run ProGuard from Ant.
32  *
33  * @author Eric Lafortune
34  */
35 public class ProGuardTask extends ConfigurationTask
36 {
37     // Ant task attributes.
38 
setConfiguration(File configurationFile)39     public void setConfiguration(File configurationFile) throws BuildException
40     {
41         try
42         {
43             // Get the combined system properties and Ant properties, for
44             // replacing ProGuard-style properties ('<...>').
45             Properties properties = new Properties();
46             properties.putAll(getProject().getProperties());
47 
48             ConfigurationParser parser = new ConfigurationParser(configurationFile,
49                                                                  properties);
50             try
51             {
52                 parser.parse(configuration);
53             }
54             catch (ParseException e)
55             {
56                 throw new BuildException(e.getMessage(), e);
57             }
58             finally
59             {
60                 parser.close();
61             }
62         }
63         catch (IOException e)
64         {
65             throw new BuildException(e.getMessage(), e);
66         }
67     }
68 
69 
70     /**
71      * @deprecated Use the nested outjar element instead.
72      */
setOutjar(String parameters)73     public void setOutjar(String parameters)
74     {
75         throw new BuildException("Use the <outjar> nested element instead of the 'outjar' attribute");
76     }
77 
78 
setSkipnonpubliclibraryclasses(boolean skipNonPublicLibraryClasses)79     public void setSkipnonpubliclibraryclasses(boolean skipNonPublicLibraryClasses)
80     {
81         configuration.skipNonPublicLibraryClasses = skipNonPublicLibraryClasses;
82     }
83 
84 
setSkipnonpubliclibraryclassmembers(boolean skipNonPublicLibraryClassMembers)85     public void setSkipnonpubliclibraryclassmembers(boolean skipNonPublicLibraryClassMembers)
86     {
87         configuration.skipNonPublicLibraryClassMembers = skipNonPublicLibraryClassMembers;
88     }
89 
90 
setTarget(String target)91     public void setTarget(String target)
92     {
93         configuration.targetClassVersion = ClassUtil.internalClassVersion(target);
94         if (configuration.targetClassVersion == 0)
95         {
96             throw new BuildException("Unsupported target '"+target+"'");
97         }
98     }
99 
100 
setForceprocessing(boolean forceProcessing)101     public void setForceprocessing(boolean forceProcessing)
102     {
103         configuration.lastModified = forceProcessing ? Long.MAX_VALUE : 0;
104     }
105 
106 
setPrintseeds(File printSeeds)107     public void setPrintseeds(File printSeeds)
108     {
109         configuration.printSeeds = optionalFile(printSeeds);
110     }
111 
112 
setShrink(boolean shrink)113     public void setShrink(boolean shrink)
114     {
115         configuration.shrink = shrink;
116     }
117 
118 
setPrintusage(File printUsage)119     public void setPrintusage(File printUsage)
120     {
121         configuration.printUsage = optionalFile(printUsage);
122     }
123 
124 
setOptimize(boolean optimize)125     public void setOptimize(boolean optimize)
126     {
127         configuration.optimize = optimize;
128     }
129 
130 
setOptimizationpasses(int optimizationPasses)131     public void setOptimizationpasses(int optimizationPasses)
132     {
133         configuration.optimizationPasses = optimizationPasses;
134     }
135 
136 
setAllowaccessmodification(boolean allowAccessModification)137     public void setAllowaccessmodification(boolean allowAccessModification)
138     {
139         configuration.allowAccessModification = allowAccessModification;
140     }
141 
142 
setMergeinterfacesaggressively(boolean mergeinterfacesaggressively)143     public void setMergeinterfacesaggressively(boolean mergeinterfacesaggressively)
144     {
145         configuration.mergeInterfacesAggressively = mergeinterfacesaggressively;
146     }
147 
148 
setObfuscate(boolean obfuscate)149     public void setObfuscate(boolean obfuscate)
150     {
151         configuration.obfuscate = obfuscate;
152     }
153 
154 
setPrintmapping(File printMapping)155     public void setPrintmapping(File printMapping)
156     {
157         configuration.printMapping = optionalFile(printMapping);
158     }
159 
160 
setApplymapping(File applyMapping)161     public void setApplymapping(File applyMapping)
162     {
163         configuration.applyMapping = resolvedFile(applyMapping);
164     }
165 
166 
setObfuscationdictionary(File obfuscationDictionary)167     public void setObfuscationdictionary(File obfuscationDictionary)
168     {
169         configuration.obfuscationDictionary = resolvedFile(obfuscationDictionary);
170     }
171 
172 
setClassobfuscationdictionary(File classObfuscationDictionary)173     public void setClassobfuscationdictionary(File classObfuscationDictionary)
174     {
175         configuration.classObfuscationDictionary = resolvedFile(classObfuscationDictionary);
176     }
177 
178 
setPackageobfuscationdictionary(File packageObfuscationDictionary)179     public void setPackageobfuscationdictionary(File packageObfuscationDictionary)
180     {
181         configuration.packageObfuscationDictionary = resolvedFile(packageObfuscationDictionary);
182     }
183 
184 
setOverloadaggressively(boolean overloadAggressively)185     public void setOverloadaggressively(boolean overloadAggressively)
186     {
187         configuration.overloadAggressively = overloadAggressively;
188     }
189 
190 
setUseuniqueclassmembernames(boolean useUniqueClassMemberNames)191     public void setUseuniqueclassmembernames(boolean useUniqueClassMemberNames)
192     {
193         configuration.useUniqueClassMemberNames = useUniqueClassMemberNames;
194     }
195 
196 
setUsemixedcaseclassnames(boolean useMixedCaseClassNames)197     public void setUsemixedcaseclassnames(boolean useMixedCaseClassNames)
198     {
199         configuration.useMixedCaseClassNames = useMixedCaseClassNames;
200     }
201 
202 
setFlattenpackagehierarchy(String flattenPackageHierarchy)203     public void setFlattenpackagehierarchy(String flattenPackageHierarchy)
204     {
205         configuration.flattenPackageHierarchy = ClassUtil.internalClassName(flattenPackageHierarchy);
206     }
207 
208 
setRepackageclasses(String repackageClasses)209     public void setRepackageclasses(String repackageClasses)
210     {
211         configuration.repackageClasses = ClassUtil.internalClassName(repackageClasses);
212     }
213 
214     /**
215      * @deprecated Use the repackageclasses attribute instead.
216      */
setDefaultpackage(String defaultPackage)217     public void setDefaultpackage(String defaultPackage)
218     {
219         configuration.repackageClasses = ClassUtil.internalClassName(defaultPackage);
220     }
221 
222 
setKeepparameternames(boolean keepParameterNames)223     public void setKeepparameternames(boolean keepParameterNames)
224     {
225         configuration.keepParameterNames = keepParameterNames;
226     }
227 
228 
setRenamesourcefileattribute(String newSourceFileAttribute)229     public void setRenamesourcefileattribute(String newSourceFileAttribute)
230     {
231         configuration.newSourceFileAttribute = newSourceFileAttribute;
232     }
233 
234 
setPreverify(boolean preverify)235     public void setPreverify(boolean preverify)
236     {
237         configuration.preverify = preverify;
238     }
239 
240 
setMicroedition(boolean microEdition)241     public void setMicroedition(boolean microEdition)
242     {
243         configuration.microEdition = microEdition;
244     }
245 
246 
setVerbose(boolean verbose)247     public void setVerbose(boolean verbose)
248     {
249         configuration.verbose = verbose;
250     }
251 
252 
setNote(boolean note)253     public void setNote(boolean note)
254     {
255         if (note)
256         {
257             // Switch on notes if they were completely disabled.
258             if (configuration.note != null &&
259                 configuration.note.isEmpty())
260             {
261                 configuration.note = null;
262             }
263         }
264         else
265         {
266             // Switch off notes.
267             configuration.note = new ArrayList();
268         }
269     }
270 
271 
setWarn(boolean warn)272     public void setWarn(boolean warn)
273     {
274         if (warn)
275         {
276             // Switch on warnings if they were completely disabled.
277             if (configuration.warn != null &&
278                 configuration.warn.isEmpty())
279             {
280                 configuration.warn = null;
281             }
282         }
283         else
284         {
285             // Switch off warnings.
286             configuration.warn = new ArrayList();
287         }
288     }
289 
290 
setIgnorewarnings(boolean ignoreWarnings)291     public void setIgnorewarnings(boolean ignoreWarnings)
292     {
293         configuration.ignoreWarnings = ignoreWarnings;
294     }
295 
296 
setPrintconfiguration(File printConfiguration)297     public void setPrintconfiguration(File printConfiguration)
298     {
299         configuration.printConfiguration = optionalFile(printConfiguration);
300     }
301 
302 
setDump(File dump)303     public void setDump(File dump)
304     {
305         configuration.dump = optionalFile(dump);
306     }
307 
308 
309     // Implementations for Task.
310 
execute()311     public void execute() throws BuildException
312     {
313         try
314         {
315             ProGuard proGuard = new ProGuard(configuration);
316             proGuard.execute();
317         }
318         catch (IOException e)
319         {
320             throw new BuildException(e.getMessage(), e);
321         }
322     }
323 
324 
325     // Small utility methods.
326 
327     /**
328      * Returns a file that is properly resolved with respect to the project
329      * directory, or <code>null</code> or empty if its name is actually a
330      * boolean flag.
331      */
optionalFile(File file)332     private File optionalFile(File file)
333     {
334         String fileName = file.getName();
335 
336         return
337             fileName.equalsIgnoreCase("false") ||
338             fileName.equalsIgnoreCase("no")    ||
339             fileName.equalsIgnoreCase("off")    ? null :
340             fileName.equalsIgnoreCase("true")  ||
341             fileName.equalsIgnoreCase("yes")   ||
342             fileName.equalsIgnoreCase("on")     ? Configuration.STD_OUT :
343                                                   resolvedFile(file);
344     }
345 
346 
347     /**
348      * Returns a file that is properly resolved with respect to the project
349      * directory.
350      */
resolvedFile(File file)351     private File resolvedFile(File file)
352     {
353         return file.isAbsolute() ? file :
354                                    new File(getProject().getBaseDir(),
355                                             file.getName());
356     }
357 }
358