1920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson/* 2920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Copyright (C) 2010 Google Inc. 3920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * 4920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Licensed under the Apache License, Version 2.0 (the "License"); 5920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * you may not use this file except in compliance with the License. 6920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * You may obtain a copy of the License at 7920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * 8920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * http://www.apache.org/licenses/LICENSE-2.0 9920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * 10920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Unless required by applicable law or agreed to in writing, software 11920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * distributed under the License is distributed on an "AS IS" BASIS, 12920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 13920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * See the License for the specific language governing permissions and 14920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * limitations under the License. 15920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 16920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 17920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpackage com.google.doclava; 18920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 19920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.JSilver; 20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.data.Data; 21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.resourceloader.CompositeResourceLoader; 22920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.resourceloader.FileSystemResourceLoader; 23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport com.google.clearsilver.jsilver.resourceloader.ResourceLoader; 24920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.File; 25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.FileOutputStream; 26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.IOException; 27920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.io.OutputStreamWriter; 28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.net.URL; 29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.ArrayList; 30920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.Collections; 31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.HashMap; 32920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.LinkedHashSet; 33920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.List; 34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.Map; 35920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.Set; 36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson/** 38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * This class is used to generate a web page highlighting the differences and 39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * similarities among various Java libraries. 40920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * 41920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 42920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpublic final class DoclavaDiff { 43920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private final String outputDir; 44920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private final JSilver jSilver; 45920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private final List<FederatedSite> sites = new ArrayList<FederatedSite>(); 46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 47920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson public static void main(String[] args) { 48920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson new DoclavaDiff(args).generateSite(); 49920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 50920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 51920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson public DoclavaDiff(String[] args) { 52920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // TODO: options parsing 53920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson try { 54920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson sites.add(new FederatedSite("Android", new URL("http://manatee/doclava/android"))); 55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson sites.add(new FederatedSite("GWT", new URL("http://manatee/doclava/gwt"))); 56920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson //sites.add(new FederatedSite("Crore", new URL("http://manatee/doclava/crore"))); 57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson outputDir = "build"; 58920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } catch (Exception e) { 59920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson throw new AssertionError(e); 60920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 62920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson // TODO: accept external templates 63920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<ResourceLoader> resourceLoaders = new ArrayList<ResourceLoader>(); 64920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson resourceLoaders.add(new FileSystemResourceLoader("assets/templates")); 65920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 66920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ResourceLoader compositeResourceLoader = new CompositeResourceLoader(resourceLoaders); 67920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson jSilver = new JSilver(compositeResourceLoader); 68920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 69920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 70920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson public void generateSite() { 71920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Data data = generateHdf(); 72920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson generateHtml("diff.cs", data, new File(outputDir + "/diff.html")); 73920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 74920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 75920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 76920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Creates an HDF with this structure: 77920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * <pre> 7841d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty * sites.0.name = projectA 7941d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty * sites.0.url = http://proja.domain.com/reference 8041d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty * sites.1.name = projectB 8141d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty * sites.1.url = http://projb.domain.com 82920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.name = java.lang 83920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.sites.0.hasPackage = 1 8441d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty * packages.0.sites.0.link = http://proja.domain.com/reference/java/lang 85920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.sites.1.hasPackage = 0 86920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.classes.0.qualifiedName = java.lang.Object 87920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.classes.0.sites.0.hasClass = 1 8841d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty * packages.0.classes.0.sites.0.link = http://proja.domain.com/reference/java/lang/Object 89920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.classes.0.sites.1.hasClass = 0 90920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.classes.0.methods.0.signature = wait() 91920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.classes.0.methods.0.sites.0.hasMethod = 1 9241d8656cf17e04b25a058d0874e401654ea547b4Dirk Dougherty * packages.0.classes.0.methods.0.sites.0.link = http://proja.domain.com/reference/java/lang/Object#wait 93920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * packages.0.classes.0.methods.0.sites.1.hasMethod = 0 94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * </pre> 95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private Data generateHdf() { 97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Data data = jSilver.createData(); 98920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 99920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue("triangle.opened", "../assets/templates/assets/images/triangle-opened.png"); 100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue("triangle.closed", "../assets/templates/assets/images/triangle-closed.png"); 101920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int i = 0; 103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String base = "sites." + (i++); 105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(base + ".name", site.name()); 106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(base + ".url", site.baseUrl().toString()); 107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<String> allPackages = knownPackages(sites); 110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int p = 0; 112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (String pkg : allPackages) { 113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo packageInfo = new PackageInfo(pkg); 114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String packageBase = "packages." + (p++); 115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(packageBase + ".name", pkg); 116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int s = 0; 118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String siteBase = packageBase + ".sites." + (s++); 120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (site.apiInfo().getPackages().containsKey(pkg)) { 121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".hasPackage", "1"); 122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".link", site.linkFor(packageInfo.htmlPage())); 123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".hasPackage", "0"); 125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (packageUniqueToSite(pkg, sites)) { 129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<String> packageClasses = knownClassesForPackage(pkg, sites); 133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int c = 0; 134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (String qualifiedClassName : packageClasses) { 135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String classBase = packageBase + ".classes." + (c++); 136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(classBase + ".qualifiedName", qualifiedClassName); 137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson s = 0; 139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String siteBase = classBase + ".sites." + (s++); 141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo classInfo = site.apiInfo().findClass(qualifiedClassName); 142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (classInfo != null) { 143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".hasClass", "1"); 144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".link", site.linkFor(classInfo.htmlPage())); 145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".hasClass", "0"); 147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (agreeOnClass(qualifiedClassName, sites)) { 151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 152920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 153920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 154920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (classUniqueToSite(qualifiedClassName, sites)) { 155920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 156920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 157920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 158920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int m = 0; 159920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<MethodInfo> methods = knownMethodsForClass(qualifiedClassName, sites); 160920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : methods) { 161920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (agreeOnMethod(qualifiedClassName, method, sites)) { 162920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 163920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 164920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 165920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String methodBase = classBase + ".methods." + (m++); 166920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(methodBase + ".signature", method.prettySignature()); 167920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int k = 0; 168920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 169920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String siteBase = methodBase + ".sites." + (k++); 170920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (site.apiInfo().findClass(qualifiedClassName) == null) { 171920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".hasMethod", "0"); 172920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 173920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 174920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Map<String,MethodInfo> siteMethods 175920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson = site.apiInfo().findClass(qualifiedClassName).allMethods(); 176920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (siteMethods.containsKey(method.getHashableName())) { 177920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".hasMethod", "1"); 178920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".link", site.linkFor(method.htmlPage())); 179920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } else { 180920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson data.setValue(siteBase + ".hasMethod", "0"); 181920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 182920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 183920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 184920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 185920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 186920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 187920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return data; 188920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 189920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 190920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 191920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns a list of all known packages from all sites. 192920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 193920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private List<String> knownPackages(List<FederatedSite> sites) { 194920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Set<String> allPackages = new LinkedHashSet<String>(); 195920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 196920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Map<String, PackageInfo> packages = site.apiInfo().getPackages(); 197920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (String pkg : packages.keySet()) { 198920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson allPackages.add(pkg); 199920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 200920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 201920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 202920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<String> packages = new ArrayList<String>(allPackages); 203920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Collections.sort(packages); 204920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return packages; 205920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 206920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 207920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 208920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns all known classes from all sites for a given package. 209920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 210920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private List<String> knownClassesForPackage(String pkg, List<FederatedSite> sites) { 211920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Set<String> allClasses = new LinkedHashSet<String>(); 212920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 213920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo packageInfo = site.apiInfo().getPackages().get(pkg); 214920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (packageInfo == null) { 215920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 216920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 217920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson HashMap<String, ClassInfo> classes = packageInfo.allClasses(); 218920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (Map.Entry<String, ClassInfo> entry : classes.entrySet()) { 219920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson allClasses.add(entry.getValue().qualifiedName()); 220920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 221920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 222920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 223920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<String> classes = new ArrayList<String>(allClasses); 224920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Collections.sort(classes); 225920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return classes; 226920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 227920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 228920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 229920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns all known methods from all sites for a given class. 230920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 231920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private List<MethodInfo> knownMethodsForClass(String qualifiedClassName, 232920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<FederatedSite> sites) { 233920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 234920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson Map<String, MethodInfo> allMethods = new HashMap<String, MethodInfo>(); 235920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 236920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo classInfo = site.apiInfo().findClass(qualifiedClassName); 237920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (classInfo == null) { 238920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 239920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 240920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 241920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (Map.Entry<String, MethodInfo> entry: classInfo.allMethods().entrySet()) { 242920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson allMethods.put(entry.getKey(), entry.getValue()); 243920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 244920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 245920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 246920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<MethodInfo> methods = new ArrayList<MethodInfo>(); 247920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson methods.addAll(allMethods.values()); 248920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return methods; 249920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 250920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 251920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 252920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns true if the list of sites all completely agree on the given 253920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * package. All sites must possess the package, all classes it contains, and 254920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * all methods of each class. 255920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 256920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private boolean agreeOnPackage(String pkg, List<FederatedSite> sites) { 257920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 258920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (site.apiInfo().getPackages().get(pkg) == null) { 259920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 260920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 261920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 262920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 263920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<String> classes = knownClassesForPackage(pkg, sites); 264920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (String clazz : classes) { 265920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!agreeOnClass(clazz, sites)) { 266920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 267920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 268920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 269920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 270920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 271920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 272920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 273920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns true if the list of sites all agree on the given class. Each site 274920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * must have the class and agree on its methods. 275920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 276920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private boolean agreeOnClass(String qualifiedClassName, List<FederatedSite> sites) { 277920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<MethodInfo> methods = knownMethodsForClass(qualifiedClassName, sites); 278920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : methods) { 279920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!agreeOnMethod(qualifiedClassName, method, sites)) { 280920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 281920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 282920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 283920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 284920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 285920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 286920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 287920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns true if the list of sites all contain the given method. 288920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 289920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private boolean agreeOnMethod(String qualifiedClassName, MethodInfo method, 290920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson List<FederatedSite> sites) { 291920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 292920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 293920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo siteClass = site.apiInfo().findClass(qualifiedClassName); 294920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (siteClass == null) { 295920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 296920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 297920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 298920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (!siteClass.supportsMethod(method)) { 299920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return false; 300920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 301920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 302920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return true; 303920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 304920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 305920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 306920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns true if the given package is known to exactly one of the given sites. 307920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 308920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private boolean packageUniqueToSite(String pkg, List<FederatedSite> sites) { 309920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int numSites = 0; 310920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 311920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (site.apiInfo().getPackages().containsKey(pkg)) { 312920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson numSites++; 313920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 314920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 315920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return numSites == 1; 316920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 317920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 318920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 319920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Returns true if the given class is known to exactly one of the given sites. 320920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 321920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private boolean classUniqueToSite(String qualifiedClassName, List<FederatedSite> sites) { 322920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson int numSites = 0; 323920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : sites) { 324920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (site.apiInfo().findClass(qualifiedClassName) != null) { 325920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson numSites++; 326920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 327920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 328920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson return numSites == 1; 329920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 330920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 331920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private void generateHtml(String template, Data data, File file) { 332920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClearPage.ensureDirectory(file); 333920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 334920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson OutputStreamWriter stream = null; 335920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson try { 336920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream = new OutputStreamWriter(new FileOutputStream(file), "UTF-8"); 337920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson String rendered = jSilver.render(template, data); 338920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.write(rendered, 0, rendered.length()); 339920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } catch (IOException e) { 340920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson System.out.println("error: " + e.getMessage() + "; when writing file: " + file.getAbsolutePath()); 341920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } finally { 342920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (stream != null) { 343920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson try { 344920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson stream.close(); 345920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } catch (IOException ignored) {} 346920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 347920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 348920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 349ed8f79791885c3ac15401d88a147aee551e1039eBrian Carlstrom} 350