ConfigurationTask.java revision cfead78069f3dc32998dc118ee08cab3867acea2
1/*
2 * ProGuard -- shrinking, optimization, obfuscation, and preverification
3 *             of Java bytecode.
4 *
5 * Copyright (c) 2002-2011 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(arg,
297                                                                 "embedded configuration",
298                                                                 getProject().getBaseDir());
299
300            try
301            {
302                parser.parse(configuration);
303            }
304            catch (ParseException ex)
305            {
306                throw new BuildException(ex.getMessage());
307            }
308            finally
309            {
310                parser.close();
311            }
312        }
313        catch (IOException ex)
314        {
315            throw new BuildException(ex.getMessage());
316        }
317    }
318
319
320    // Small utility methods.
321
322    private ClassPath extendClassPath(ClassPath        classPath,
323                                      ClassPathElement classPathElement,
324                                      boolean          output)
325    {
326        if (classPath == null)
327        {
328            classPath = new ClassPath();
329        }
330
331        classPathElement.appendClassPathEntriesTo(classPath,
332                                                  output);
333
334        return classPath;
335    }
336
337
338    private ClassPath extendClassPath(ClassPath classPath,
339                                      ClassPath additionalClassPath)
340    {
341        if (additionalClassPath != null)
342        {
343            if (classPath == null)
344            {
345                classPath = new ClassPath();
346            }
347
348            classPath.addAll(additionalClassPath);
349        }
350
351        return classPath;
352    }
353
354
355    private List extendKeepSpecifications(List                     keepSpecifications,
356                                          KeepSpecificationElement keepSpecificationElement,
357                                          boolean                  markClasses,
358                                          boolean                  markClassesConditionally)
359    {
360        if (keepSpecifications == null)
361        {
362            keepSpecifications = new ArrayList();
363        }
364
365        keepSpecificationElement.appendTo(keepSpecifications,
366                                          markClasses,
367                                          markClassesConditionally);
368
369        return keepSpecifications;
370    }
371
372
373    private List extendClassSpecifications(List                      classSpecifications,
374                                           ClassSpecificationElement classSpecificationElement)
375    {
376        if (classSpecifications == null)
377        {
378            classSpecifications = new ArrayList();
379        }
380
381        classSpecificationElement.appendTo(classSpecifications);
382
383        return classSpecifications;
384    }
385
386
387    private List extendClassSpecifications(List classSpecifications,
388                                           List additionalClassSpecifications)
389    {
390        if (additionalClassSpecifications != null)
391        {
392            if (classSpecifications == null)
393            {
394                classSpecifications = new ArrayList();
395            }
396
397            classSpecifications.addAll(additionalClassSpecifications);
398        }
399
400        return classSpecifications;
401    }
402
403
404    private List extendFilter(List          filter,
405                              FilterElement filterElement)
406    {
407        return extendFilter(filter, filterElement, false);
408    }
409
410
411    private List extendFilter(List          filter,
412                              FilterElement filterElement,
413                              boolean       internal)
414    {
415        if (filter == null)
416        {
417            filter = new ArrayList();
418        }
419
420        filterElement.appendTo(filter, internal);
421
422        return filter;
423    }
424
425
426    private List extendList(List list,
427                            List additionalList)
428    {
429        if (additionalList != null)
430        {
431            if (list == null)
432            {
433                list = new ArrayList();
434            }
435
436            list.addAll(additionalList);
437        }
438
439        return list;
440    }
441}
442