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.tonicsystems.jarjar.util.*; 20 import java.io.File; 21 import java.io.IOException; 22 import java.util.*; 23 24 class MainProcessor implements JarProcessor 25 { 26 private final boolean verbose; 27 private final JarProcessorChain chain; 28 private final KeepProcessor kp; 29 private final Map<String, String> renames = new HashMap<String, String>(); 30 MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest)31 public MainProcessor(List<PatternElement> patterns, boolean verbose, boolean skipManifest) { 32 this.verbose = verbose; 33 List<Zap> zapList = new ArrayList<Zap>(); 34 List<Rule> ruleList = new ArrayList<Rule>(); 35 List<Keep> keepList = new ArrayList<Keep>(); 36 for (PatternElement pattern : patterns) { 37 if (pattern instanceof Zap) { 38 zapList.add((Zap) pattern); 39 } else if (pattern instanceof Rule) { 40 ruleList.add((Rule) pattern); 41 } else if (pattern instanceof Keep) { 42 keepList.add((Keep) pattern); 43 } 44 } 45 46 PackageRemapper pr = new PackageRemapper(ruleList, verbose); 47 kp = keepList.isEmpty() ? null : new KeepProcessor(keepList); 48 49 List<JarProcessor> processors = new ArrayList<JarProcessor>(); 50 if (skipManifest) 51 processors.add(ManifestProcessor.getInstance()); 52 if (kp != null) 53 processors.add(kp); 54 processors.add(new ZapProcessor(zapList)); 55 processors.add(new JarTransformerChain(new RemappingClassTransformer[]{ new RemappingClassTransformer(pr) })); 56 processors.add(new ResourceProcessor(pr)); 57 chain = new JarProcessorChain(processors.toArray(new JarProcessor[processors.size()])); 58 } 59 strip(File file)60 public void strip(File file) throws IOException { 61 if (kp == null) 62 return; 63 Set<String> excludes = getExcludes(); 64 if (!excludes.isEmpty()) 65 StandaloneJarProcessor.run(file, file, new ExcludeProcessor(excludes, verbose)); 66 } 67 68 /** 69 * Returns the <code>.class</code> files to delete. As well the root-parameter as the rename ones 70 * are taken in consideration, so that the concerned files are not listed in the result. 71 * 72 * @return the paths of the files in the jar-archive, including the <code>.class</code> suffix 73 */ getExcludes()74 private Set<String> getExcludes() { 75 Set<String> result = new HashSet<String>(); 76 for (String exclude : kp.getExcludes()) { 77 String name = exclude + ".class"; 78 String renamed = renames.get(name); 79 result.add((renamed != null) ? renamed : name); 80 } 81 return result; 82 } 83 84 /** 85 * 86 * @param struct 87 * @return <code>true</code> if the entry is to include in the output jar 88 * @throws IOException 89 */ process(EntryStruct struct)90 public boolean process(EntryStruct struct) throws IOException { 91 String name = struct.name; 92 boolean keepIt = chain.process(struct); 93 if (keepIt) { 94 if (!name.equals(struct.name)) { 95 if (kp != null) 96 renames.put(name, struct.name); 97 if (verbose) 98 System.err.println("Renamed " + name + " -> " + struct.name); 99 } 100 } else { 101 if (verbose) 102 System.err.println("Removed " + name); 103 } 104 return keepIt; 105 } 106 } 107