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.doclava.apicheck.ApiParseException; 20920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.net.URL; 21920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.ArrayList; 221e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamiltonimport java.util.HashMap; 23920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonimport java.util.List; 241e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamiltonimport java.util.Map; 25920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 26920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson/** 27920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Cross-references documentation among different libraries. A FederationTagger 28920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * is populated with a list of {@link FederatedSite} objects which are linked 29920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * against when overlapping content is discovered. 30920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 31920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodsonpublic final class FederationTagger { 321e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton private final Map<String, URL> federatedUrls = new HashMap<String, URL>(); 331e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton private final Map<String, String> federatedXmls = new HashMap<String, String>(); 34920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private final List<FederatedSite> federatedSites = new ArrayList<FederatedSite>(); 351e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton private boolean initialized = false; 36920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson /** 37920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * Adds a Doclava documentation site for federation. Accepts the base URL of 38920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson * the remote API. 39920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson */ 401e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton public void addSiteUrl(String name, URL site) { 411e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton federatedUrls.put(name, site); 421e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 431e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton 441e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton public void addSiteApi(String name, String file) { 451e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton federatedXmls.put(name, file); 46920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 47920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 489c584846aff32976d94246c7682a980346d12f44Jeff Hamilton public void tag(ClassInfo classDoc) { 499c584846aff32976d94246c7682a980346d12f44Jeff Hamilton initialize(); 509c584846aff32976d94246c7682a980346d12f44Jeff Hamilton for (FederatedSite site : federatedSites) { 519c584846aff32976d94246c7682a980346d12f44Jeff Hamilton applyFederation(site, new ClassInfo[] { classDoc }); 529c584846aff32976d94246c7682a980346d12f44Jeff Hamilton } 539c584846aff32976d94246c7682a980346d12f44Jeff Hamilton } 549c584846aff32976d94246c7682a980346d12f44Jeff Hamilton 55920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson public void tagAll(ClassInfo[] classDocs) { 561e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton initialize(); 57920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FederatedSite site : federatedSites) { 58920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson applyFederation(site, classDocs); 59920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 60920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 61920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 621e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton private void initialize() { 631e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton if (initialized) { 641e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton return; 651e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 661e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton 671e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton for (String name : federatedXmls.keySet()) { 681e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton if (!federatedUrls.containsKey(name)) { 691e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton Errors.error(Errors.NO_FEDERATION_DATA, null, "Unknown documentation site for " + name); 701e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 711e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 721e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton 731e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton for (String name : federatedUrls.keySet()) { 741e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton try { 751e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton if (federatedXmls.containsKey(name)) { 761e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton federatedSites.add(new FederatedSite(name, federatedUrls.get(name), 771e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton federatedXmls.get(name))); 781e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } else { 791e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton federatedSites.add(new FederatedSite(name, federatedUrls.get(name))); 801e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 811e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } catch (ApiParseException e) { 821e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton String error = "Could not add site for federation: " + name; 831e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton if (e.getMessage() != null) { 841e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton error += ": " + e.getMessage(); 851e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 861e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton Errors.error(Errors.NO_FEDERATION_DATA, null, error); 871e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 881e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 891e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton 901e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton initialized = true; 911e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton } 921e0d370c6a4c165cb8c74f53cb035e5521e0cd87Jeff Hamilton 93920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private void applyFederation(FederatedSite federationSource, ClassInfo[] classDocs) { 94920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo classDoc : classDocs) { 95920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson PackageInfo packageSpec 96920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson = federationSource.apiInfo().getPackages().get(classDoc.containingPackage().name()); 97920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 98920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (packageSpec == null) { 99920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 100920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 101920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 102920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo classSpec = packageSpec.allClasses().get(classDoc.name()); 103920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 104920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (classSpec == null) { 105920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson continue; 106920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 107920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 108920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson federateMethods(federationSource, classSpec, classDoc); 109920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson federateConstructors(federationSource, classSpec, classDoc); 110920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson federateFields(federationSource, classSpec, classDoc); 111920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson federateClass(federationSource, classDoc); 112920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson federatePackage(federationSource, classDoc.containingPackage()); 113920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 114920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 115920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 116920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private void federateMethods(FederatedSite site, ClassInfo federatedClass, ClassInfo localClass) { 117920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo method : localClass.methods()) { 118920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (ClassInfo superclass : federatedClass.hierarchy()) { 119920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (superclass.allMethods().containsKey(method.getHashableName())) { 120920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson method.addFederatedReference(site); 121920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson break; 122920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 123920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 124920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 125920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 126920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 127920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private void federateConstructors(FederatedSite site, ClassInfo federatedClass, 128920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson ClassInfo localClass) { 129920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (MethodInfo constructor : localClass.constructors()) { 130920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (federatedClass.hasConstructor(constructor)) { 131920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson constructor.addFederatedReference(site); 132920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 133920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 134920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 135920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 136920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private void federateFields(FederatedSite site, ClassInfo federatedClass, ClassInfo localClass) { 137920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson for (FieldInfo field : localClass.fields()) { 138920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson if (federatedClass.allFields().containsKey(field.name())) { 139920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson field.addFederatedReference(site); 140920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 141920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 142920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 143920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 144920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private void federateClass(FederatedSite source, ClassInfo doc) { 145920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson doc.addFederatedReference(source); 146920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 147920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson 148920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson private void federatePackage(FederatedSite source, PackageInfo pkg) { 149920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson pkg.addFederatedReference(source); 150920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson } 151920dbbbaca6aa578f3b26d89e99d12754c26ed60Ben Dodson}