/*
* 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();
}
}
}