ConfigurationTask.java revision b72c5c2e5482cf10117b2b25f642f7616b2326c3
1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2009 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 */
21package proguard.ant;
22
23import org.apache.tools.ant.*;
24import proguard.*;
25
26import java.io.IOException;
27import java.util.*;
28
29/**
30 * This Task allows to define a ProGuard configuration from Ant.
31 *
32 * @author Eric Lafortune
33 */
34public class ConfigurationTask extends Task
35{
36    protected final Configuration configuration = new Configuration();
37
38
39    /**
40     * Adds the contents of this configuration task to the given configuration.
41     * @param configuration the configuration to be extended.
42     */
43    public void appendTo(Configuration configuration)
44    {
45        // Append all of these configuration entries to the given configuration.
46        configuration.programJars               = extendClassPath(configuration.programJars,
47                                                                  this.configuration.programJars);
48
49        configuration.libraryJars               = extendClassPath(configuration.libraryJars,
50                                                                  this.configuration.libraryJars);
51
52        configuration.keep                      = extendClassSpecifications(configuration.keep,
53                                                                            this.configuration.keep);
54
55        configuration.keepDirectories           = extendList(configuration.keepDirectories,
56                                                             this.configuration.keepDirectories);
57
58        configuration.whyAreYouKeeping          = extendClassSpecifications(configuration.whyAreYouKeeping,
59                                                                            this.configuration.whyAreYouKeeping);
60
61        configuration.optimizations             = extendClassSpecifications(configuration.optimizations,
62                                                                            this.configuration.optimizations);
63
64        configuration.assumeNoSideEffects       = extendClassSpecifications(configuration.assumeNoSideEffects,
65                                                                            this.configuration.assumeNoSideEffects);
66
67        configuration.keepPackageNames          = extendList(configuration.keepPackageNames,
68                                                             this.configuration.keepPackageNames);
69
70        configuration.keepAttributes            = extendList(configuration.keepAttributes,
71                                                             this.configuration.keepAttributes);
72
73        configuration.adaptClassStrings         = extendList(configuration.adaptClassStrings,
74                                                             this.configuration.adaptClassStrings);
75
76        configuration.adaptResourceFileNames    = extendList(configuration.adaptResourceFileNames,
77                                                             this.configuration.adaptResourceFileNames);
78
79        configuration.adaptResourceFileContents = extendList(configuration.adaptResourceFileContents,
80                                                             this.configuration.adaptResourceFileContents);
81
82        configuration.note                      = extendList(configuration.note,
83                                                             this.configuration.note);
84
85        configuration.warn                      = extendList(configuration.warn,
86                                                             this.configuration.warn);
87    }
88
89
90    // Ant task nested elements.
91
92    public void addConfiguredInjar(ClassPathElement classPathElement)
93    {
94        configuration.programJars = extendClassPath(configuration.programJars,
95                                                    classPathElement,
96                                                    false);
97    }
98
99
100    public void addConfiguredOutjar(ClassPathElement classPathElement)
101    {
102        configuration.programJars = extendClassPath(configuration.programJars,
103                                                    classPathElement,
104                                                    true);
105    }
106
107
108    public void addConfiguredLibraryjar(ClassPathElement classPathElement)
109    {
110        configuration.libraryJars = extendClassPath(configuration.libraryJars,
111                                                    classPathElement,
112                                                    false);
113    }
114
115
116    public void addConfiguredKeepdirectory(FilterElement filterElement)
117    {
118        configuration.keepDirectories = extendFilter(configuration.keepDirectories,
119                                                     filterElement);
120    }
121
122
123    public void addConfiguredKeepdirectories(FilterElement filterElement)
124    {
125        configuration.keepDirectories = extendFilter(configuration.keepDirectories,
126                                                     filterElement);
127    }
128
129
130    public void addConfiguredKeep(KeepSpecificationElement keepSpecificationElement)
131    {
132        configuration.keep = extendKeepSpecifications(configuration.keep,
133                                                      keepSpecificationElement,
134                                                      true,
135                                                      false);
136    }
137
138
139    public void addConfiguredKeepclassmembers(KeepSpecificationElement keepSpecificationElement)
140    {
141        configuration.keep = extendKeepSpecifications(configuration.keep,
142                                                      keepSpecificationElement,
143                                                      false,
144                                                      false);
145    }
146
147
148    public void addConfiguredKeepclasseswithmembers(KeepSpecificationElement keepSpecificationElement)
149    {
150        configuration.keep = extendKeepSpecifications(configuration.keep,
151                                                      keepSpecificationElement,
152                                                      true,
153                                                      true);
154    }
155
156
157    public void addConfiguredKeepnames(KeepSpecificationElement keepSpecificationElement)
158    {
159        // Set the shrinking flag, based on the name (backward compatibility).
160        keepSpecificationElement.setAllowshrinking(true);
161
162        configuration.keep = extendKeepSpecifications(configuration.keep,
163                                                      keepSpecificationElement,
164                                                      true,
165                                                      false);
166    }
167
168
169    public void addConfiguredKeepclassmembernames(KeepSpecificationElement keepSpecificationElement)
170    {
171        // Set the shrinking flag, based on the name (backward compatibility).
172        keepSpecificationElement.setAllowshrinking(true);
173
174        configuration.keep = extendKeepSpecifications(configuration.keep,
175                                                      keepSpecificationElement,
176                                                      false,
177                                                      false);
178    }
179
180
181    public void addConfiguredKeepclasseswithmembernames(KeepSpecificationElement keepSpecificationElement)
182    {
183        // Set the shrinking flag, based on the name (backward compatibility).
184        keepSpecificationElement.setAllowshrinking(true);
185
186        configuration.keep = extendKeepSpecifications(configuration.keep,
187                                                      keepSpecificationElement,
188                                                      true,
189                                                      true);
190    }
191
192
193    public void addConfiguredWhyareyoukeeping(ClassSpecificationElement classSpecificationElement)
194    {
195        configuration.whyAreYouKeeping = extendClassSpecifications(configuration.whyAreYouKeeping,
196                                                                   classSpecificationElement);
197    }
198
199
200    public void addConfiguredAssumenosideeffects(ClassSpecificationElement classSpecificationElement)
201    {
202        configuration.assumeNoSideEffects = extendClassSpecifications(configuration.assumeNoSideEffects,
203                                                                      classSpecificationElement);
204    }
205
206
207    public void addConfiguredOptimizations(FilterElement filterElement)
208    {
209        addConfiguredOptimization(filterElement);
210    }
211
212
213    public void addConfiguredOptimization(FilterElement filterElement)
214    {
215        configuration.optimizations = extendFilter(configuration.optimizations,
216                                                   filterElement);
217    }
218
219
220    public void addConfiguredKeeppackagename(FilterElement filterElement)
221    {
222        configuration.keepPackageNames = extendFilter(configuration.keepPackageNames,
223                                                      filterElement,
224                                                      true);
225    }
226
227
228    public void addConfiguredKeeppackagenames(FilterElement filterElement)
229    {
230        configuration.keepPackageNames = extendFilter(configuration.keepPackageNames,
231                                                      filterElement,
232                                                      true);
233    }
234
235
236    public void addConfiguredKeepattributes(FilterElement filterElement)
237    {
238        addConfiguredKeepattribute(filterElement);
239    }
240
241
242    public void addConfiguredKeepattribute(FilterElement filterElement)
243    {
244        configuration.keepAttributes = extendFilter(configuration.keepAttributes,
245                                                    filterElement);
246    }
247
248
249    public void addConfiguredAdaptclassstrings(FilterElement filterElement)
250    {
251        configuration.adaptClassStrings = extendFilter(configuration.adaptClassStrings,
252                                                       filterElement, true);
253    }
254
255
256    public void addConfiguredAdaptresourcefilenames(FilterElement filterElement)
257    {
258        configuration.adaptResourceFileNames = extendFilter(configuration.adaptResourceFileNames,
259                                                            filterElement);
260    }
261
262
263    public void addConfiguredAdaptresourcefilecontents(FilterElement filterElement)
264    {
265        configuration.adaptResourceFileContents = extendFilter(configuration.adaptResourceFileContents,
266                                                               filterElement);
267    }
268
269
270    public void addConfiguredDontnote(FilterElement filterElement)
271    {
272        configuration.note = extendFilter(configuration.note, filterElement, true);
273    }
274
275
276    public void addConfiguredDontwarn(FilterElement filterElement)
277    {
278        configuration.warn = extendFilter(configuration.warn, filterElement, true);
279    }
280
281
282    public void addConfiguredConfiguration(ConfigurationElement configurationElement)
283    {
284        configurationElement.appendTo(configuration);
285    }
286
287
288    // Implementations for Task.
289
290    public void addText(String text) throws BuildException
291    {
292        try
293        {
294            String arg = getProject().replaceProperties(text);
295
296            ConfigurationParser parser = new ConfigurationParser(new String[] { arg },
297                                                                 getProject().getBaseDir());
298
299            try
300            {
301                parser.parse(configuration);
302            }
303            catch (ParseException ex)
304            {
305                throw new BuildException(ex.getMessage());
306            }
307            finally
308            {
309                parser.close();
310            }
311        }
312        catch (IOException ex)
313        {
314            throw new BuildException(ex.getMessage());
315        }
316    }
317
318
319    // Small utility methods.
320
321    private ClassPath extendClassPath(ClassPath        classPath,
322                                      ClassPathElement classPathElement,
323                                      boolean          output)
324    {
325        if (classPath == null)
326        {
327            classPath = new ClassPath();
328        }
329
330        classPathElement.appendClassPathEntriesTo(classPath,
331                                                  output);
332
333        return classPath;
334    }
335
336
337    private ClassPath extendClassPath(ClassPath classPath,
338                                      ClassPath additionalClassPath)
339    {
340        if (additionalClassPath != null)
341        {
342            if (classPath == null)
343            {
344                classPath = new ClassPath();
345            }
346
347            classPath.addAll(additionalClassPath);
348        }
349
350        return classPath;
351    }
352
353
354    private List extendKeepSpecifications(List                     keepSpecifications,
355                                          KeepSpecificationElement keepSpecificationElement,
356                                          boolean                  markClasses,
357                                          boolean                  markClassesConditionally)
358    {
359        if (keepSpecifications == null)
360        {
361            keepSpecifications = new ArrayList();
362        }
363
364        keepSpecificationElement.appendTo(keepSpecifications,
365                                          markClasses,
366                                          markClassesConditionally);
367
368        return keepSpecifications;
369    }
370
371
372    private List extendClassSpecifications(List                      classSpecifications,
373                                           ClassSpecificationElement classSpecificationElement)
374    {
375        if (classSpecifications == null)
376        {
377            classSpecifications = new ArrayList();
378        }
379
380        classSpecificationElement.appendTo(classSpecifications);
381
382        return classSpecifications;
383    }
384
385
386    private List extendClassSpecifications(List classSpecifications,
387                                           List additionalClassSpecifications)
388    {
389        if (additionalClassSpecifications != null)
390        {
391            if (classSpecifications == null)
392            {
393                classSpecifications = new ArrayList();
394            }
395
396            classSpecifications.addAll(additionalClassSpecifications);
397        }
398
399        return classSpecifications;
400    }
401
402
403    private List extendFilter(List          filter,
404                              FilterElement filterElement)
405    {
406        return extendFilter(filter, filterElement, false);
407    }
408
409
410    private List extendFilter(List          filter,
411                              FilterElement filterElement,
412                              boolean       internal)
413    {
414        if (filter == null)
415        {
416            filter = new ArrayList();
417        }
418
419        filterElement.appendTo(filter, internal);
420
421        return filter;
422    }
423
424
425    private List extendList(List list,
426                            List additionalList)
427    {
428        if (additionalList != null)
429        {
430            if (list == null)
431            {
432                list = new ArrayList();
433            }
434
435            list.addAll(additionalList);
436        }
437
438        return list;
439    }
440}
441