1*feeed43cSAndroid Build Coastguard Worker /* 2*feeed43cSAndroid Build Coastguard Worker * Copyright (C) 2010 Google Inc. 3*feeed43cSAndroid Build Coastguard Worker * 4*feeed43cSAndroid Build Coastguard Worker * Licensed under the Apache License, Version 2.0 (the "License"); 5*feeed43cSAndroid Build Coastguard Worker * you may not use this file except in compliance with the License. 6*feeed43cSAndroid Build Coastguard Worker * You may obtain a copy of the License at 7*feeed43cSAndroid Build Coastguard Worker * 8*feeed43cSAndroid Build Coastguard Worker * http://www.apache.org/licenses/LICENSE-2.0 9*feeed43cSAndroid Build Coastguard Worker * 10*feeed43cSAndroid Build Coastguard Worker * Unless required by applicable law or agreed to in writing, software 11*feeed43cSAndroid Build Coastguard Worker * distributed under the License is distributed on an "AS IS" BASIS, 12*feeed43cSAndroid Build Coastguard Worker * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13*feeed43cSAndroid Build Coastguard Worker * See the License for the specific language governing permissions and 14*feeed43cSAndroid Build Coastguard Worker * limitations under the License. 15*feeed43cSAndroid Build Coastguard Worker */ 16*feeed43cSAndroid Build Coastguard Worker 17*feeed43cSAndroid Build Coastguard Worker package com.google.doclava; 18*feeed43cSAndroid Build Coastguard Worker 19*feeed43cSAndroid Build Coastguard Worker import com.google.clearsilver.jsilver.JSilver; 20*feeed43cSAndroid Build Coastguard Worker import com.google.clearsilver.jsilver.data.Data; 21*feeed43cSAndroid Build Coastguard Worker import com.google.clearsilver.jsilver.resourceloader.CompositeResourceLoader; 22*feeed43cSAndroid Build Coastguard Worker import com.google.clearsilver.jsilver.resourceloader.FileSystemResourceLoader; 23*feeed43cSAndroid Build Coastguard Worker import com.google.clearsilver.jsilver.resourceloader.ResourceLoader; 24*feeed43cSAndroid Build Coastguard Worker import java.io.File; 25*feeed43cSAndroid Build Coastguard Worker import java.io.FileOutputStream; 26*feeed43cSAndroid Build Coastguard Worker import java.io.IOException; 27*feeed43cSAndroid Build Coastguard Worker import java.io.OutputStreamWriter; 28*feeed43cSAndroid Build Coastguard Worker import java.net.URL; 29*feeed43cSAndroid Build Coastguard Worker import java.util.ArrayList; 30*feeed43cSAndroid Build Coastguard Worker import java.util.Collections; 31*feeed43cSAndroid Build Coastguard Worker import java.util.HashMap; 32*feeed43cSAndroid Build Coastguard Worker import java.util.LinkedHashSet; 33*feeed43cSAndroid Build Coastguard Worker import java.util.List; 34*feeed43cSAndroid Build Coastguard Worker import java.util.Map; 35*feeed43cSAndroid Build Coastguard Worker import java.util.Set; 36*feeed43cSAndroid Build Coastguard Worker 37*feeed43cSAndroid Build Coastguard Worker /** 38*feeed43cSAndroid Build Coastguard Worker * This class is used to generate a web page highlighting the differences and 39*feeed43cSAndroid Build Coastguard Worker * similarities among various Java libraries. 40*feeed43cSAndroid Build Coastguard Worker * 41*feeed43cSAndroid Build Coastguard Worker */ 42*feeed43cSAndroid Build Coastguard Worker public final class DoclavaDiff { 43*feeed43cSAndroid Build Coastguard Worker private final String outputDir; 44*feeed43cSAndroid Build Coastguard Worker private final JSilver jSilver; 45*feeed43cSAndroid Build Coastguard Worker private final List<FederatedSite> sites = new ArrayList<FederatedSite>(); 46*feeed43cSAndroid Build Coastguard Worker main(String[] args)47*feeed43cSAndroid Build Coastguard Worker public static void main(String[] args) { 48*feeed43cSAndroid Build Coastguard Worker new DoclavaDiff(args).generateSite(); 49*feeed43cSAndroid Build Coastguard Worker } 50*feeed43cSAndroid Build Coastguard Worker DoclavaDiff(String[] args)51*feeed43cSAndroid Build Coastguard Worker public DoclavaDiff(String[] args) { 52*feeed43cSAndroid Build Coastguard Worker // TODO: options parsing 53*feeed43cSAndroid Build Coastguard Worker try { 54*feeed43cSAndroid Build Coastguard Worker sites.add(new FederatedSite("Android", new URL("http://manatee/doclava/android"))); 55*feeed43cSAndroid Build Coastguard Worker sites.add(new FederatedSite("GWT", new URL("http://manatee/doclava/gwt"))); 56*feeed43cSAndroid Build Coastguard Worker //sites.add(new FederatedSite("Crore", new URL("http://manatee/doclava/crore"))); 57*feeed43cSAndroid Build Coastguard Worker outputDir = "build"; 58*feeed43cSAndroid Build Coastguard Worker } catch (Exception e) { 59*feeed43cSAndroid Build Coastguard Worker throw new AssertionError(e); 60*feeed43cSAndroid Build Coastguard Worker } 61*feeed43cSAndroid Build Coastguard Worker 62*feeed43cSAndroid Build Coastguard Worker // TODO: accept external templates 63*feeed43cSAndroid Build Coastguard Worker List<ResourceLoader> resourceLoaders = new ArrayList<ResourceLoader>(); 64*feeed43cSAndroid Build Coastguard Worker resourceLoaders.add(new FileSystemResourceLoader("assets/templates")); 65*feeed43cSAndroid Build Coastguard Worker 66*feeed43cSAndroid Build Coastguard Worker ResourceLoader compositeResourceLoader = new CompositeResourceLoader(resourceLoaders); 67*feeed43cSAndroid Build Coastguard Worker jSilver = new JSilver(compositeResourceLoader); 68*feeed43cSAndroid Build Coastguard Worker } 69*feeed43cSAndroid Build Coastguard Worker generateSite()70*feeed43cSAndroid Build Coastguard Worker public void generateSite() { 71*feeed43cSAndroid Build Coastguard Worker Data data = generateHdf(); 72*feeed43cSAndroid Build Coastguard Worker generateHtml("diff.cs", data, new File(outputDir + "/diff.html")); 73*feeed43cSAndroid Build Coastguard Worker } 74*feeed43cSAndroid Build Coastguard Worker 75*feeed43cSAndroid Build Coastguard Worker /** 76*feeed43cSAndroid Build Coastguard Worker * Creates an HDF with this structure: 77*feeed43cSAndroid Build Coastguard Worker * <pre> 78*feeed43cSAndroid Build Coastguard Worker * sites.0.name = projectA 79*feeed43cSAndroid Build Coastguard Worker * sites.0.url = http://proja.domain.com/reference 80*feeed43cSAndroid Build Coastguard Worker * sites.1.name = projectB 81*feeed43cSAndroid Build Coastguard Worker * sites.1.url = http://projb.domain.com 82*feeed43cSAndroid Build Coastguard Worker * packages.0.name = java.lang 83*feeed43cSAndroid Build Coastguard Worker * packages.0.sites.0.hasPackage = 1 84*feeed43cSAndroid Build Coastguard Worker * packages.0.sites.0.link = http://proja.domain.com/reference/java/lang 85*feeed43cSAndroid Build Coastguard Worker * packages.0.sites.1.hasPackage = 0 86*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.qualifiedName = java.lang.Object 87*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.sites.0.hasClass = 1 88*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.sites.0.link = http://proja.domain.com/reference/java/lang/Object 89*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.sites.1.hasClass = 0 90*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.methods.0.signature = wait() 91*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.methods.0.sites.0.hasMethod = 1 92*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.methods.0.sites.0.link = http://proja.domain.com/reference/java/lang/Object#wait 93*feeed43cSAndroid Build Coastguard Worker * packages.0.classes.0.methods.0.sites.1.hasMethod = 0 94*feeed43cSAndroid Build Coastguard Worker * </pre> 95*feeed43cSAndroid Build Coastguard Worker */ generateHdf()96*feeed43cSAndroid Build Coastguard Worker private Data generateHdf() { 97*feeed43cSAndroid Build Coastguard Worker Data data = jSilver.createData(); 98*feeed43cSAndroid Build Coastguard Worker 99*feeed43cSAndroid Build Coastguard Worker data.setValue("triangle.opened", "../assets/templates/assets/images/triangle-opened.png"); 100*feeed43cSAndroid Build Coastguard Worker data.setValue("triangle.closed", "../assets/templates/assets/images/triangle-closed.png"); 101*feeed43cSAndroid Build Coastguard Worker 102*feeed43cSAndroid Build Coastguard Worker int i = 0; 103*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 104*feeed43cSAndroid Build Coastguard Worker String base = "sites." + (i++); 105*feeed43cSAndroid Build Coastguard Worker data.setValue(base + ".name", site.name()); 106*feeed43cSAndroid Build Coastguard Worker data.setValue(base + ".url", site.baseUrl().toString()); 107*feeed43cSAndroid Build Coastguard Worker } 108*feeed43cSAndroid Build Coastguard Worker 109*feeed43cSAndroid Build Coastguard Worker List<String> allPackages = knownPackages(sites); 110*feeed43cSAndroid Build Coastguard Worker 111*feeed43cSAndroid Build Coastguard Worker int p = 0; 112*feeed43cSAndroid Build Coastguard Worker for (String pkg : allPackages) { 113*feeed43cSAndroid Build Coastguard Worker PackageInfo packageInfo = new PackageInfo(pkg); 114*feeed43cSAndroid Build Coastguard Worker String packageBase = "packages." + (p++); 115*feeed43cSAndroid Build Coastguard Worker data.setValue(packageBase + ".name", pkg); 116*feeed43cSAndroid Build Coastguard Worker 117*feeed43cSAndroid Build Coastguard Worker int s = 0; 118*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 119*feeed43cSAndroid Build Coastguard Worker String siteBase = packageBase + ".sites." + (s++); 120*feeed43cSAndroid Build Coastguard Worker if (site.apiInfo().getPackages().containsKey(pkg)) { 121*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".hasPackage", "1"); 122*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".link", site.linkFor(packageInfo.htmlPage())); 123*feeed43cSAndroid Build Coastguard Worker } else { 124*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".hasPackage", "0"); 125*feeed43cSAndroid Build Coastguard Worker } 126*feeed43cSAndroid Build Coastguard Worker } 127*feeed43cSAndroid Build Coastguard Worker 128*feeed43cSAndroid Build Coastguard Worker if (packageUniqueToSite(pkg, sites)) { 129*feeed43cSAndroid Build Coastguard Worker continue; 130*feeed43cSAndroid Build Coastguard Worker } 131*feeed43cSAndroid Build Coastguard Worker 132*feeed43cSAndroid Build Coastguard Worker List<String> packageClasses = knownClassesForPackage(pkg, sites); 133*feeed43cSAndroid Build Coastguard Worker int c = 0; 134*feeed43cSAndroid Build Coastguard Worker for (String qualifiedClassName : packageClasses) { 135*feeed43cSAndroid Build Coastguard Worker String classBase = packageBase + ".classes." + (c++); 136*feeed43cSAndroid Build Coastguard Worker data.setValue(classBase + ".qualifiedName", qualifiedClassName); 137*feeed43cSAndroid Build Coastguard Worker 138*feeed43cSAndroid Build Coastguard Worker s = 0; 139*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 140*feeed43cSAndroid Build Coastguard Worker String siteBase = classBase + ".sites." + (s++); 141*feeed43cSAndroid Build Coastguard Worker ClassInfo classInfo = site.apiInfo().findClass(qualifiedClassName); 142*feeed43cSAndroid Build Coastguard Worker if (classInfo != null) { 143*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".hasClass", "1"); 144*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".link", site.linkFor(classInfo.htmlPage())); 145*feeed43cSAndroid Build Coastguard Worker } else { 146*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".hasClass", "0"); 147*feeed43cSAndroid Build Coastguard Worker } 148*feeed43cSAndroid Build Coastguard Worker } 149*feeed43cSAndroid Build Coastguard Worker 150*feeed43cSAndroid Build Coastguard Worker if (agreeOnClass(qualifiedClassName, sites)) { 151*feeed43cSAndroid Build Coastguard Worker continue; 152*feeed43cSAndroid Build Coastguard Worker } 153*feeed43cSAndroid Build Coastguard Worker 154*feeed43cSAndroid Build Coastguard Worker if (classUniqueToSite(qualifiedClassName, sites)) { 155*feeed43cSAndroid Build Coastguard Worker continue; 156*feeed43cSAndroid Build Coastguard Worker } 157*feeed43cSAndroid Build Coastguard Worker 158*feeed43cSAndroid Build Coastguard Worker int m = 0; 159*feeed43cSAndroid Build Coastguard Worker List<MethodInfo> methods = knownMethodsForClass(qualifiedClassName, sites); 160*feeed43cSAndroid Build Coastguard Worker for (MethodInfo method : methods) { 161*feeed43cSAndroid Build Coastguard Worker if (agreeOnMethod(qualifiedClassName, method, sites)) { 162*feeed43cSAndroid Build Coastguard Worker continue; 163*feeed43cSAndroid Build Coastguard Worker } 164*feeed43cSAndroid Build Coastguard Worker 165*feeed43cSAndroid Build Coastguard Worker String methodBase = classBase + ".methods." + (m++); 166*feeed43cSAndroid Build Coastguard Worker data.setValue(methodBase + ".signature", method.prettySignature()); 167*feeed43cSAndroid Build Coastguard Worker int k = 0; 168*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 169*feeed43cSAndroid Build Coastguard Worker String siteBase = methodBase + ".sites." + (k++); 170*feeed43cSAndroid Build Coastguard Worker if (site.apiInfo().findClass(qualifiedClassName) == null) { 171*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".hasMethod", "0"); 172*feeed43cSAndroid Build Coastguard Worker continue; 173*feeed43cSAndroid Build Coastguard Worker } 174*feeed43cSAndroid Build Coastguard Worker Map<String,MethodInfo> siteMethods 175*feeed43cSAndroid Build Coastguard Worker = site.apiInfo().findClass(qualifiedClassName).allMethods(); 176*feeed43cSAndroid Build Coastguard Worker if (siteMethods.containsKey(method.getHashableName())) { 177*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".hasMethod", "1"); 178*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".link", site.linkFor(method.htmlPage())); 179*feeed43cSAndroid Build Coastguard Worker } else { 180*feeed43cSAndroid Build Coastguard Worker data.setValue(siteBase + ".hasMethod", "0"); 181*feeed43cSAndroid Build Coastguard Worker } 182*feeed43cSAndroid Build Coastguard Worker } 183*feeed43cSAndroid Build Coastguard Worker } 184*feeed43cSAndroid Build Coastguard Worker } 185*feeed43cSAndroid Build Coastguard Worker } 186*feeed43cSAndroid Build Coastguard Worker 187*feeed43cSAndroid Build Coastguard Worker return data; 188*feeed43cSAndroid Build Coastguard Worker } 189*feeed43cSAndroid Build Coastguard Worker 190*feeed43cSAndroid Build Coastguard Worker /** 191*feeed43cSAndroid Build Coastguard Worker * Returns a list of all known packages from all sites. 192*feeed43cSAndroid Build Coastguard Worker */ knownPackages(List<FederatedSite> sites)193*feeed43cSAndroid Build Coastguard Worker private List<String> knownPackages(List<FederatedSite> sites) { 194*feeed43cSAndroid Build Coastguard Worker Set<String> allPackages = new LinkedHashSet<String>(); 195*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 196*feeed43cSAndroid Build Coastguard Worker Map<String, PackageInfo> packages = site.apiInfo().getPackages(); 197*feeed43cSAndroid Build Coastguard Worker for (String pkg : packages.keySet()) { 198*feeed43cSAndroid Build Coastguard Worker allPackages.add(pkg); 199*feeed43cSAndroid Build Coastguard Worker } 200*feeed43cSAndroid Build Coastguard Worker } 201*feeed43cSAndroid Build Coastguard Worker 202*feeed43cSAndroid Build Coastguard Worker List<String> packages = new ArrayList<String>(allPackages); 203*feeed43cSAndroid Build Coastguard Worker Collections.sort(packages); 204*feeed43cSAndroid Build Coastguard Worker return packages; 205*feeed43cSAndroid Build Coastguard Worker } 206*feeed43cSAndroid Build Coastguard Worker 207*feeed43cSAndroid Build Coastguard Worker /** 208*feeed43cSAndroid Build Coastguard Worker * Returns all known classes from all sites for a given package. 209*feeed43cSAndroid Build Coastguard Worker */ knownClassesForPackage(String pkg, List<FederatedSite> sites)210*feeed43cSAndroid Build Coastguard Worker private List<String> knownClassesForPackage(String pkg, List<FederatedSite> sites) { 211*feeed43cSAndroid Build Coastguard Worker Set<String> allClasses = new LinkedHashSet<String>(); 212*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 213*feeed43cSAndroid Build Coastguard Worker PackageInfo packageInfo = site.apiInfo().getPackages().get(pkg); 214*feeed43cSAndroid Build Coastguard Worker if (packageInfo == null) { 215*feeed43cSAndroid Build Coastguard Worker continue; 216*feeed43cSAndroid Build Coastguard Worker } 217*feeed43cSAndroid Build Coastguard Worker HashMap<String, ClassInfo> classes = packageInfo.allClasses(); 218*feeed43cSAndroid Build Coastguard Worker for (Map.Entry<String, ClassInfo> entry : classes.entrySet()) { 219*feeed43cSAndroid Build Coastguard Worker allClasses.add(entry.getValue().qualifiedName()); 220*feeed43cSAndroid Build Coastguard Worker } 221*feeed43cSAndroid Build Coastguard Worker } 222*feeed43cSAndroid Build Coastguard Worker 223*feeed43cSAndroid Build Coastguard Worker List<String> classes = new ArrayList<String>(allClasses); 224*feeed43cSAndroid Build Coastguard Worker Collections.sort(classes); 225*feeed43cSAndroid Build Coastguard Worker return classes; 226*feeed43cSAndroid Build Coastguard Worker } 227*feeed43cSAndroid Build Coastguard Worker 228*feeed43cSAndroid Build Coastguard Worker /** 229*feeed43cSAndroid Build Coastguard Worker * Returns all known methods from all sites for a given class. 230*feeed43cSAndroid Build Coastguard Worker */ knownMethodsForClass(String qualifiedClassName, List<FederatedSite> sites)231*feeed43cSAndroid Build Coastguard Worker private List<MethodInfo> knownMethodsForClass(String qualifiedClassName, 232*feeed43cSAndroid Build Coastguard Worker List<FederatedSite> sites) { 233*feeed43cSAndroid Build Coastguard Worker 234*feeed43cSAndroid Build Coastguard Worker Map<String, MethodInfo> allMethods = new HashMap<String, MethodInfo>(); 235*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 236*feeed43cSAndroid Build Coastguard Worker ClassInfo classInfo = site.apiInfo().findClass(qualifiedClassName); 237*feeed43cSAndroid Build Coastguard Worker if (classInfo == null) { 238*feeed43cSAndroid Build Coastguard Worker continue; 239*feeed43cSAndroid Build Coastguard Worker } 240*feeed43cSAndroid Build Coastguard Worker 241*feeed43cSAndroid Build Coastguard Worker for (Map.Entry<String, MethodInfo> entry: classInfo.allMethods().entrySet()) { 242*feeed43cSAndroid Build Coastguard Worker allMethods.put(entry.getKey(), entry.getValue()); 243*feeed43cSAndroid Build Coastguard Worker } 244*feeed43cSAndroid Build Coastguard Worker } 245*feeed43cSAndroid Build Coastguard Worker 246*feeed43cSAndroid Build Coastguard Worker List<MethodInfo> methods = new ArrayList<MethodInfo>(); 247*feeed43cSAndroid Build Coastguard Worker methods.addAll(allMethods.values()); 248*feeed43cSAndroid Build Coastguard Worker return methods; 249*feeed43cSAndroid Build Coastguard Worker } 250*feeed43cSAndroid Build Coastguard Worker 251*feeed43cSAndroid Build Coastguard Worker /** 252*feeed43cSAndroid Build Coastguard Worker * Returns true if the list of sites all completely agree on the given 253*feeed43cSAndroid Build Coastguard Worker * package. All sites must possess the package, all classes it contains, and 254*feeed43cSAndroid Build Coastguard Worker * all methods of each class. 255*feeed43cSAndroid Build Coastguard Worker */ agreeOnPackage(String pkg, List<FederatedSite> sites)256*feeed43cSAndroid Build Coastguard Worker private boolean agreeOnPackage(String pkg, List<FederatedSite> sites) { 257*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 258*feeed43cSAndroid Build Coastguard Worker if (site.apiInfo().getPackages().get(pkg) == null) { 259*feeed43cSAndroid Build Coastguard Worker return false; 260*feeed43cSAndroid Build Coastguard Worker } 261*feeed43cSAndroid Build Coastguard Worker } 262*feeed43cSAndroid Build Coastguard Worker 263*feeed43cSAndroid Build Coastguard Worker List<String> classes = knownClassesForPackage(pkg, sites); 264*feeed43cSAndroid Build Coastguard Worker for (String clazz : classes) { 265*feeed43cSAndroid Build Coastguard Worker if (!agreeOnClass(clazz, sites)) { 266*feeed43cSAndroid Build Coastguard Worker return false; 267*feeed43cSAndroid Build Coastguard Worker } 268*feeed43cSAndroid Build Coastguard Worker } 269*feeed43cSAndroid Build Coastguard Worker return true; 270*feeed43cSAndroid Build Coastguard Worker } 271*feeed43cSAndroid Build Coastguard Worker 272*feeed43cSAndroid Build Coastguard Worker /** 273*feeed43cSAndroid Build Coastguard Worker * Returns true if the list of sites all agree on the given class. Each site 274*feeed43cSAndroid Build Coastguard Worker * must have the class and agree on its methods. 275*feeed43cSAndroid Build Coastguard Worker */ agreeOnClass(String qualifiedClassName, List<FederatedSite> sites)276*feeed43cSAndroid Build Coastguard Worker private boolean agreeOnClass(String qualifiedClassName, List<FederatedSite> sites) { 277*feeed43cSAndroid Build Coastguard Worker List<MethodInfo> methods = knownMethodsForClass(qualifiedClassName, sites); 278*feeed43cSAndroid Build Coastguard Worker for (MethodInfo method : methods) { 279*feeed43cSAndroid Build Coastguard Worker if (!agreeOnMethod(qualifiedClassName, method, sites)) { 280*feeed43cSAndroid Build Coastguard Worker return false; 281*feeed43cSAndroid Build Coastguard Worker } 282*feeed43cSAndroid Build Coastguard Worker } 283*feeed43cSAndroid Build Coastguard Worker return true; 284*feeed43cSAndroid Build Coastguard Worker } 285*feeed43cSAndroid Build Coastguard Worker 286*feeed43cSAndroid Build Coastguard Worker /** 287*feeed43cSAndroid Build Coastguard Worker * Returns true if the list of sites all contain the given method. 288*feeed43cSAndroid Build Coastguard Worker */ agreeOnMethod(String qualifiedClassName, MethodInfo method, List<FederatedSite> sites)289*feeed43cSAndroid Build Coastguard Worker private boolean agreeOnMethod(String qualifiedClassName, MethodInfo method, 290*feeed43cSAndroid Build Coastguard Worker List<FederatedSite> sites) { 291*feeed43cSAndroid Build Coastguard Worker 292*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 293*feeed43cSAndroid Build Coastguard Worker ClassInfo siteClass = site.apiInfo().findClass(qualifiedClassName); 294*feeed43cSAndroid Build Coastguard Worker if (siteClass == null) { 295*feeed43cSAndroid Build Coastguard Worker return false; 296*feeed43cSAndroid Build Coastguard Worker } 297*feeed43cSAndroid Build Coastguard Worker 298*feeed43cSAndroid Build Coastguard Worker if (!siteClass.supportsMethod(method)) { 299*feeed43cSAndroid Build Coastguard Worker return false; 300*feeed43cSAndroid Build Coastguard Worker } 301*feeed43cSAndroid Build Coastguard Worker } 302*feeed43cSAndroid Build Coastguard Worker return true; 303*feeed43cSAndroid Build Coastguard Worker } 304*feeed43cSAndroid Build Coastguard Worker 305*feeed43cSAndroid Build Coastguard Worker /** 306*feeed43cSAndroid Build Coastguard Worker * Returns true if the given package is known to exactly one of the given sites. 307*feeed43cSAndroid Build Coastguard Worker */ packageUniqueToSite(String pkg, List<FederatedSite> sites)308*feeed43cSAndroid Build Coastguard Worker private boolean packageUniqueToSite(String pkg, List<FederatedSite> sites) { 309*feeed43cSAndroid Build Coastguard Worker int numSites = 0; 310*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 311*feeed43cSAndroid Build Coastguard Worker if (site.apiInfo().getPackages().containsKey(pkg)) { 312*feeed43cSAndroid Build Coastguard Worker numSites++; 313*feeed43cSAndroid Build Coastguard Worker } 314*feeed43cSAndroid Build Coastguard Worker } 315*feeed43cSAndroid Build Coastguard Worker return numSites == 1; 316*feeed43cSAndroid Build Coastguard Worker } 317*feeed43cSAndroid Build Coastguard Worker 318*feeed43cSAndroid Build Coastguard Worker /** 319*feeed43cSAndroid Build Coastguard Worker * Returns true if the given class is known to exactly one of the given sites. 320*feeed43cSAndroid Build Coastguard Worker */ classUniqueToSite(String qualifiedClassName, List<FederatedSite> sites)321*feeed43cSAndroid Build Coastguard Worker private boolean classUniqueToSite(String qualifiedClassName, List<FederatedSite> sites) { 322*feeed43cSAndroid Build Coastguard Worker int numSites = 0; 323*feeed43cSAndroid Build Coastguard Worker for (FederatedSite site : sites) { 324*feeed43cSAndroid Build Coastguard Worker if (site.apiInfo().findClass(qualifiedClassName) != null) { 325*feeed43cSAndroid Build Coastguard Worker numSites++; 326*feeed43cSAndroid Build Coastguard Worker } 327*feeed43cSAndroid Build Coastguard Worker } 328*feeed43cSAndroid Build Coastguard Worker return numSites == 1; 329*feeed43cSAndroid Build Coastguard Worker } 330*feeed43cSAndroid Build Coastguard Worker generateHtml(String template, Data data, File file)331*feeed43cSAndroid Build Coastguard Worker private void generateHtml(String template, Data data, File file) { 332*feeed43cSAndroid Build Coastguard Worker ClearPage.ensureDirectory(file); 333*feeed43cSAndroid Build Coastguard Worker 334*feeed43cSAndroid Build Coastguard Worker OutputStreamWriter stream = null; 335*feeed43cSAndroid Build Coastguard Worker try { 336*feeed43cSAndroid Build Coastguard Worker stream = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); 337*feeed43cSAndroid Build Coastguard Worker String rendered = jSilver.render(template, data); 338*feeed43cSAndroid Build Coastguard Worker stream.write(rendered, 0, rendered.length()); 339*feeed43cSAndroid Build Coastguard Worker } catch (IOException e) { 340*feeed43cSAndroid Build Coastguard Worker System.out.println("error: " + e.getMessage() + "; when writing file: " + file.getAbsolutePath()); 341*feeed43cSAndroid Build Coastguard Worker } finally { 342*feeed43cSAndroid Build Coastguard Worker if (stream != null) { 343*feeed43cSAndroid Build Coastguard Worker try { 344*feeed43cSAndroid Build Coastguard Worker stream.close(); 345*feeed43cSAndroid Build Coastguard Worker } catch (IOException ignored) {} 346*feeed43cSAndroid Build Coastguard Worker } 347*feeed43cSAndroid Build Coastguard Worker } 348*feeed43cSAndroid Build Coastguard Worker } 349*feeed43cSAndroid Build Coastguard Worker } 350