1 /* 2 * Copyright (C) 2009 The Android Open Source Project 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 signature.compare; 18 19 import signature.UsageException; 20 import signature.compare.model.IApiDelta; 21 import signature.compare.model.IPackageDelta; 22 import signature.compare.model.impl.SigDelta; 23 import signature.converter.Visibility; 24 import signature.converter.dex.DexFactory; 25 import signature.converter.doclet.DocletFactory; 26 import signature.io.IApiDeltaExternalizer; 27 import signature.io.IApiLoader; 28 import signature.io.html.HtmlDeltaExternalizer; 29 import signature.io.impl.BinaryApi; 30 import signature.model.IApi; 31 32 import java.io.IOException; 33 import java.util.Collections; 34 import java.util.HashSet; 35 import java.util.Set; 36 37 /** 38 * Driver class for the --compare option. 39 */ 40 public class Main { 41 42 /** 43 * <pre> 44 * --from=(doclet | dex | sig) <sourcefiles> 45 * --name <name> 46 * --to=(doclet | dex | sig) <sourcefiles> 47 * --name <name> 48 * --out directory 49 * --packages packageName{ packageName} 50 * </pre> 51 */ main(String[] args)52 public static void main(String[] args) throws IOException { 53 int at = 0; 54 55 if (!"--from".equals(args[at])) { 56 throw new UsageException(); 57 } 58 String fromType = args[++at]; 59 60 boolean hasName = false; 61 Set<String> fromFiles = new HashSet<String>(); 62 ++at; 63 for (/* at */; at < args.length; at++) { 64 if ("--name".equals(args[at])) { 65 hasName = true; 66 break; 67 } 68 if ("--to".equals(args[at])) { 69 break; 70 } 71 fromFiles.add(args[at]); 72 } 73 74 String nameFrom = null; 75 if (hasName) { 76 nameFrom = ""; 77 if (!"--name".equals(args[at])) { 78 throw new UsageException(); 79 } 80 ++at; 81 for (/* at */; at < args.length; at++) { 82 if ("--to".equals(args[at])) { 83 break; 84 } 85 nameFrom += args[at]; 86 nameFrom += " "; 87 } 88 nameFrom = nameFrom.trim(); 89 } 90 91 if (!"--to".equals(args[at])) { 92 throw new UsageException(); 93 } 94 String toType = args[++at]; 95 96 hasName = false; 97 Set<String> toFiles = new HashSet<String>(); 98 ++at; 99 for (/* at */; at < args.length; at++) { 100 if ("--name".equals(args[at])) { 101 hasName = true; 102 break; 103 } 104 if ("--out".equals(args[at])) { 105 break; 106 } 107 toFiles.add(args[at]); 108 } 109 110 String nameTo = null; 111 if (hasName) { 112 nameTo = ""; 113 if (!"--name".equals(args[at])) { 114 throw new UsageException(); 115 } 116 ++at; 117 for (/* at */; at < args.length; at++) { 118 if ("--out".equals(args[at])) { 119 break; 120 } 121 nameTo += args[at]; 122 nameTo += " "; 123 } 124 nameTo = nameTo.trim(); 125 } 126 127 if (!"--out".equals(args[at])) { 128 throw new UsageException(); 129 } 130 String output = args[++at]; 131 132 if (!"--packages".equals(args[++at])) { 133 throw new UsageException(); 134 } 135 Set<String> packages = new HashSet<String>(); 136 ++at; 137 for (/* at */; at < args.length; at++) { 138 packages.add(args[at]); 139 } 140 141 IApiComparator comparator = new ApiComparator(); 142 IApi fromApi = getApi(fromType, nameFrom, fromFiles, packages); 143 IApi toApi = getApi(toType, nameTo, toFiles, packages); 144 145 IApiDeltaExternalizer externalizer = new HtmlDeltaExternalizer(); 146 System.out.println("Writing delta report to " + output); 147 IApiDelta delta = comparator.compare(fromApi, toApi); 148 if (delta == null) { 149 delta = new EmptyDelta(fromApi, toApi); 150 } 151 152 externalizer.externalize(output, delta); 153 } 154 155 private static class EmptyDelta extends SigDelta<IApi> implements 156 IApiDelta { EmptyDelta(IApi from, IApi to)157 public EmptyDelta(IApi from, IApi to) { 158 super(from, to); 159 } 160 getPackageDeltas()161 public Set<IPackageDelta> getPackageDeltas() { 162 return Collections.emptySet(); 163 } 164 } 165 getApi(String specType, String name, Set<String> fileNames, Set<String> packageNames)166 private static IApi getApi(String specType, String name, 167 Set<String> fileNames, Set<String> packageNames) throws 168 IOException { 169 System.out.println("Loading " + name + " of type " + specType 170 + " from " + fileNames); 171 IApiLoader factory = null; 172 if ("doclet".equals(specType)) { 173 checkName(name); 174 factory = new DocletFactory(); 175 } else if ("dex".equals(specType)) { 176 checkName(name); 177 factory = new DexFactory(); 178 } else if ("sig".equals(specType)) { 179 factory = new BinaryApi(); 180 } else { 181 throw new UsageException(); 182 } 183 return factory.loadApi(name, Visibility.PROTECTED, fileNames, 184 packageNames); 185 } 186 checkName(String name)187 private static void checkName(String name) { 188 if (name == null) { 189 throw new UsageException(); 190 } 191 } 192 } 193