• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /**
2  * Copyright 2007 Google Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 package com.tonicsystems.jarjar;
18 
19 import com.android.jarjar.StripAnnotation;
20 import com.tonicsystems.jarjar.util.*;
21 import java.io.File;
22 import java.io.IOException;
23 import java.util.*;
24 
25 import com.android.jarjar.RemoveAndroidCompatAnnotationsJarTransformer;
26 import com.android.jarjar.StripAnnotationsJarTransformer;
27 
28 class MainProcessor implements JarProcessor
29 {
30     private final boolean verbose;
31     private final JarProcessorChain chain;
32     private final KeepProcessor kp;
33     private final Map<String, String> renames = new HashMap<String, String>();
34 
35     // ANDROID-BEGIN: b/146418363 Add an Android-specific transformer to strip compat annotation
MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest)36     public MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest) {
37         this(patterns, verbose, skipManifest, false /* removeAndroidCompatAnnotations */);
38     }
39 
MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest, boolean removeAndroidCompatAnnotations)40     public MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest,
41             boolean removeAndroidCompatAnnotations) {
42         // ANDROID-END: b/146418363 Add an Android-specific transformer to strip compat annotation
43         this.verbose = verbose;
44         List<Zap> zapList = new ArrayList<Zap>();
45         List<Rule> ruleList = new ArrayList<Rule>();
46         List<Keep> keepList = new ArrayList<Keep>();
47         // ANDROID-BEGIN: b/222743634 Strip annotations from system module stubs
48         List<StripAnnotation> stripAnnotationList = new ArrayList<StripAnnotation>();
49         // ANDROID-END: b/222743634 Strip annotations from system module stubs
50         for (PatternElement pattern : patterns) {
51             if (pattern instanceof Zap) {
52                 zapList.add((Zap) pattern);
53             } else if (pattern instanceof Rule) {
54                 ruleList.add((Rule) pattern);
55             } else if (pattern instanceof Keep) {
56                 keepList.add((Keep) pattern);
57             // ANDROID-BEGIN: b/222743634 Strip annotations from system module stubs
58             } else if (pattern instanceof StripAnnotation) {
59                 stripAnnotationList.add((StripAnnotation) pattern);
60             }
61             // ANDROID-END: b/222743634 Strip annotations from system module stubs
62         }
63 
64         PackageRemapper pr = new PackageRemapper(ruleList, verbose);
65         kp = keepList.isEmpty() ? null : new KeepProcessor(keepList);
66 
67         List<JarProcessor> processors = new ArrayList<JarProcessor>();
68         if (skipManifest)
69             processors.add(ManifestProcessor.getInstance());
70         if (kp != null)
71             processors.add(kp);
72         processors.add(new ZapProcessor(zapList));
73         // ANDROID-BEGIN: b/146418363 Add an Android-specific transformer to strip compat annotation
74         if (removeAndroidCompatAnnotations)
75             processors.add(new RemoveAndroidCompatAnnotationsJarTransformer(pr));
76         // ANDROID-END: b/146418363 Add an Android-specific transformer to strip compat annotation
77         // ANDROID-BEGIN: b/222743634 Strip annotations from system module stubs
78         if (!stripAnnotationList.isEmpty()) {
79             processors.add(new StripAnnotationsJarTransformer(stripAnnotationList));
80         }
81         // ANDROID-END: b/222743634 Strip annotations from system module stubs
82         processors.add(new JarTransformerChain(new RemappingClassTransformer[]{ new RemappingClassTransformer(pr) }));
83         processors.add(new ResourceProcessor(pr));
84         chain = new JarProcessorChain(processors.toArray(new JarProcessor[processors.size()]));
85     }
86 
strip(File file)87     public void strip(File file) throws IOException {
88         if (kp == null)
89             return;
90         Set<String> excludes = getExcludes();
91         if (!excludes.isEmpty())
92             StandaloneJarProcessor.run(file, file, new ExcludeProcessor(excludes, verbose));
93     }
94 
95     /**
96      * Returns the <code>.class</code> files to delete. As well the root-parameter as the rename ones
97      * are taken in consideration, so that the concerned files are not listed in the result.
98      *
99      * @return the paths of the files in the jar-archive, including the <code>.class</code> suffix
100      */
getExcludes()101     private Set<String> getExcludes() {
102         Set<String> result = new HashSet<String>();
103         for (String exclude : kp.getExcludes()) {
104             String name = exclude + ".class";
105             String renamed = renames.get(name);
106             result.add((renamed != null) ? renamed : name);
107         }
108         return result;
109     }
110 
111     /**
112      *
113      * @param struct
114      * @return <code>true</code> if the entry is to include in the output jar
115      * @throws IOException
116      */
process(EntryStruct struct)117     public boolean process(EntryStruct struct) throws IOException {
118         String name = struct.name;
119         boolean keepIt = chain.process(struct);
120         if (keepIt) {
121             if (!name.equals(struct.name)) {
122                 if (kp != null)
123                     renames.put(name, struct.name);
124                 if (verbose)
125                     System.err.println("Renamed " + name + " -> " + struct.name);
126             }
127         } else {
128             if (verbose)
129                 System.err.println("Removed " + name);
130         }
131         return keepIt;
132     }
133 }
134