/* * Copyright (C) 2009 The Android Open Source Project * * Licensed under the Apache License, Version 2.0 (the "License"); * you may not use this file except in compliance with the License. * You may obtain a copy of the License at * * http://www.apache.org/licenses/LICENSE-2.0 * * Unless required by applicable law or agreed to in writing, software * distributed under the License is distributed on an "AS IS" BASIS, * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. * See the License for the specific language governing permissions and * limitations under the License. */ package signature.compare; import signature.UsageException; import signature.compare.model.IApiDelta; import signature.compare.model.IPackageDelta; import signature.compare.model.impl.SigDelta; import signature.converter.Visibility; import signature.converter.dex.DexFactory; import signature.converter.doclet.DocletFactory; import signature.io.IApiDeltaExternalizer; import signature.io.IApiLoader; import signature.io.html.HtmlDeltaExternalizer; import signature.io.impl.BinaryApi; import signature.model.IApi; import java.io.IOException; import java.util.Collections; import java.util.HashSet; import java.util.Set; /** * Driver class for the --compare option. */ public class Main { /** * <pre> * --from=(doclet | dex | sig) <sourcefiles> * --name <name> * --to=(doclet | dex | sig) <sourcefiles> * --name <name> * --out directory * --packages packageName{ packageName} * </pre> */ public static void main(String[] args) throws IOException { int at = 0; if (!"--from".equals(args[at])) { throw new UsageException(); } String fromType = args[++at]; boolean hasName = false; Set<String> fromFiles = new HashSet<String>(); ++at; for (/* at */; at < args.length; at++) { if ("--name".equals(args[at])) { hasName = true; break; } if ("--to".equals(args[at])) { break; } fromFiles.add(args[at]); } String nameFrom = null; if (hasName) { nameFrom = ""; if (!"--name".equals(args[at])) { throw new UsageException(); } ++at; for (/* at */; at < args.length; at++) { if ("--to".equals(args[at])) { break; } nameFrom += args[at]; nameFrom += " "; } nameFrom = nameFrom.trim(); } if (!"--to".equals(args[at])) { throw new UsageException(); } String toType = args[++at]; hasName = false; Set<String> toFiles = new HashSet<String>(); ++at; for (/* at */; at < args.length; at++) { if ("--name".equals(args[at])) { hasName = true; break; } if ("--out".equals(args[at])) { break; } toFiles.add(args[at]); } String nameTo = null; if (hasName) { nameTo = ""; if (!"--name".equals(args[at])) { throw new UsageException(); } ++at; for (/* at */; at < args.length; at++) { if ("--out".equals(args[at])) { break; } nameTo += args[at]; nameTo += " "; } nameTo = nameTo.trim(); } if (!"--out".equals(args[at])) { throw new UsageException(); } String output = args[++at]; if (!"--packages".equals(args[++at])) { throw new UsageException(); } Set<String> packages = new HashSet<String>(); ++at; for (/* at */; at < args.length; at++) { packages.add(args[at]); } IApiComparator comparator = new ApiComparator(); IApi fromApi = getApi(fromType, nameFrom, fromFiles, packages); IApi toApi = getApi(toType, nameTo, toFiles, packages); IApiDeltaExternalizer externalizer = new HtmlDeltaExternalizer(); System.out.println("Writing delta report to " + output); IApiDelta delta = comparator.compare(fromApi, toApi); if (delta == null) { delta = new EmptyDelta(fromApi, toApi); } externalizer.externalize(output, delta); } private static class EmptyDelta extends SigDelta<IApi> implements IApiDelta { public EmptyDelta(IApi from, IApi to) { super(from, to); } public Set<IPackageDelta> getPackageDeltas() { return Collections.emptySet(); } } private static IApi getApi(String specType, String name, Set<String> fileNames, Set<String> packageNames) throws IOException { System.out.println("Loading " + name + " of type " + specType + " from " + fileNames); IApiLoader factory = null; if ("doclet".equals(specType)) { checkName(name); factory = new DocletFactory(); } else if ("dex".equals(specType)) { checkName(name); factory = new DexFactory(); } else if ("sig".equals(specType)) { factory = new BinaryApi(); } else { throw new UsageException(); } return factory.loadApi(name, Visibility.PROTECTED, fileNames, packageNames); } private static void checkName(String name) { if (name == null) { throw new UsageException(); } } }