Home | History | Annotate | Download | only in compare
      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      */
     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 {
    157         public EmptyDelta(IApi from, IApi to) {
    158             super(from, to);
    159         }
    160 
    161         public Set<IPackageDelta> getPackageDeltas() {
    162             return Collections.emptySet();
    163         }
    164     }
    165 
    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 
    187     private static void checkName(String name) {
    188         if (name == null) {
    189             throw new UsageException();
    190         }
    191     }
    192 }
    193