| /******************************************************************************* |
| * Copyright (c) 2005 IBM Corporation and others. |
| * All rights reserved. This program and the accompanying materials |
| * are made available under the terms of the Eclipse Public License v1.0 |
| * which accompanies this distribution, and is available at |
| * http://www.eclipse.org/legal/epl-v10.html |
| * |
| * Contributors: |
| * IBM Corporation - initial API and implementation |
| *******************************************************************************/ |
| |
| package org.eclipse.wtp.releng.tools.component.api.compatibility; |
| |
| import java.io.ByteArrayInputStream; |
| import java.io.File; |
| import java.io.FileOutputStream; |
| import java.io.IOException; |
| import java.util.ArrayList; |
| import java.util.Collection; |
| import java.util.List; |
| import java.util.Map; |
| |
| import org.eclipse.wtp.releng.tools.component.CommandOptionParser; |
| import org.eclipse.wtp.releng.tools.component.ILocation; |
| import org.eclipse.wtp.releng.tools.component.ILocationVisitor; |
| import org.eclipse.wtp.releng.tools.component.api.API2ComponentAPI; |
| import org.eclipse.wtp.releng.tools.component.api.ClassAPI; |
| import org.eclipse.wtp.releng.tools.component.api.ComponentAPI; |
| import org.eclipse.wtp.releng.tools.component.api.FieldAPI; |
| import org.eclipse.wtp.releng.tools.component.api.MethodAPI; |
| import org.eclipse.wtp.releng.tools.component.api.PackageAPI; |
| import org.eclipse.wtp.releng.tools.component.images.ImagesUtil; |
| import org.eclipse.wtp.releng.tools.component.internal.FileLocation; |
| import org.eclipse.wtp.releng.tools.component.internal.Location; |
| import org.eclipse.wtp.releng.tools.component.xsl.XSLUtil; |
| |
| public class APICompatibilityScanner |
| { |
| private String outputDir; |
| private boolean html; |
| private String xsl; |
| |
| public String getOutputDir() |
| { |
| return outputDir; |
| } |
| |
| public void setOutputDir(String outputDir) |
| { |
| this.outputDir = addTrailingSeperator(outputDir); |
| } |
| |
| public boolean isHtml() |
| { |
| return html; |
| } |
| |
| public void setHtml(boolean html) |
| { |
| this.html = html; |
| } |
| |
| public String getXsl() |
| { |
| return xsl; |
| } |
| |
| public void setXsl(String xsl) |
| { |
| this.xsl = xsl; |
| } |
| |
| private List apiCompXMLs = new ArrayList(); |
| |
| public void execute() |
| { |
| String currOutputDir = outputDir + "1/"; |
| final String refOutputDir = outputDir + "2/"; |
| |
| // Iterate through api-info.xml for the current build |
| ILocation outputLoc = Location.createLocation(new File(currOutputDir)); |
| outputLoc.accept(new ILocationVisitor() |
| { |
| public boolean accept(ILocation location) |
| { |
| if (location.getName().endsWith("api-info.xml")) |
| { |
| try |
| { |
| ComponentAPI currCompAPI = new ComponentAPI(); |
| currCompAPI.setLocation(location); |
| currCompAPI.load(); |
| String compName = currCompAPI.getName(); |
| apiCompXMLs.add(compName); |
| StringBuffer sb = new StringBuffer(); |
| sb.append(refOutputDir); |
| sb.append(compName); |
| sb.append("/api-info.xml"); |
| ComponentAPI refCompAPI = new ComponentAPI(); |
| File f = new File(sb.toString()); |
| if (f.exists()) |
| { |
| refCompAPI.setLocation(new FileLocation(f)); |
| refCompAPI.load(); |
| } |
| else |
| { |
| refCompAPI.setName(compName); |
| } |
| genAPICompatibilityXML(currCompAPI, refCompAPI); |
| } |
| catch (IOException ioe) |
| { |
| ioe.printStackTrace(); |
| } |
| } |
| return true; |
| } |
| }); |
| |
| // Iterate through api-info.xml for the reference build |
| outputLoc = Location.createLocation(new File(refOutputDir)); |
| outputLoc.accept(new ILocationVisitor() |
| { |
| public boolean accept(ILocation location) |
| { |
| if (location.getName().endsWith("api-info.xml")) |
| { |
| try |
| { |
| ComponentAPI refCompAPI = new ComponentAPI(); |
| refCompAPI.setLocation(location); |
| refCompAPI.load(); |
| String compName = refCompAPI.getName(); |
| if (!apiCompXMLs.contains(compName)) |
| { |
| ComponentAPI currCompAPI = new ComponentAPI(); |
| currCompAPI.setName(compName); |
| genAPICompatibilityXML(currCompAPI, refCompAPI); |
| } |
| } |
| catch (IOException ioe) |
| { |
| ioe.printStackTrace(); |
| } |
| } |
| return true; |
| } |
| }); |
| |
| // Generate HTML |
| if (isHtml()) |
| { |
| ImagesUtil.copyAll(outputDir); |
| genHTML(); |
| } |
| } |
| |
| private APICompatibility genAPICompatibilityXML(ComponentAPI currCompAPI, ComponentAPI refCompAPI) throws IOException |
| { |
| APICompatibility apiCompatibility = new APICompatibility(); |
| String compName = currCompAPI.getName(); |
| apiCompatibility.setName(compName); |
| List currPkgAPIs = new ArrayList(currCompAPI.getPackageAPIs()); |
| List refPkgAPIs = new ArrayList(refCompAPI.getPackageAPIs()); |
| for (int i = 0; i < currPkgAPIs.size(); i++) |
| { |
| PackageAPI currPkgAPI = (PackageAPI)currPkgAPIs.get(i); |
| for (int j = 0; j < refPkgAPIs.size(); j++) |
| { |
| PackageAPI refPkgAPI = (PackageAPI)refPkgAPIs.get(j); |
| if (currPkgAPI.getName().equals(refPkgAPI.getName())) |
| { |
| genAPICompatibilityXML(apiCompatibility, currPkgAPI, refPkgAPI); |
| break; |
| } |
| } |
| } |
| StringBuffer location = new StringBuffer(); |
| location.append(outputDir); |
| location.append(compName); |
| location.append("/api-comp.xml"); |
| apiCompatibility.setLocation(new FileLocation(new File(location.toString()))); |
| apiCompatibility.save(); |
| return apiCompatibility; |
| } |
| |
| private void genAPICompatibilityXML(APICompatibility apiCompatibility, PackageAPI currPkgAPI, PackageAPI refPkgAPI) |
| { |
| List currClassAPIs = new ArrayList(currPkgAPI.getClassAPIs()); |
| List refClassAPIs = new ArrayList(refPkgAPI.getClassAPIs()); |
| for (int i = 0; i < currClassAPIs.size(); i++) |
| { |
| ClassAPI currClassAPI = (ClassAPI)currClassAPIs.get(i); |
| for (int j = 0; j < refClassAPIs.size(); j++) |
| { |
| ClassAPI refClassAPI = (ClassAPI)refClassAPIs.get(j); |
| if (currClassAPI.getName().equals(refClassAPI.getName())) |
| { |
| genAPICompatibilityXML(apiCompatibility, currClassAPI, refClassAPI); |
| if (refClassAPI.sizeMethodAPIs() == 0 && refClassAPI.sizeFieldAPIs() == 0) |
| refPkgAPI.removeClassAPI(refClassAPI); |
| if (currClassAPI.sizeMethodAPIs() == 0 && currClassAPI.sizeFieldAPIs() == 0) |
| currPkgAPI.removeClassAPI(currClassAPI); |
| break; |
| } |
| } |
| } |
| if (currPkgAPI.sizeClassAPI() > 0) |
| apiCompatibility.addNewAPI(currPkgAPI); |
| if (refPkgAPI.sizeClassAPI() > 0) |
| apiCompatibility.addRemovedAPI(refPkgAPI); |
| } |
| |
| private void genAPICompatibilityXML(APICompatibility apiCompatibility, ClassAPI currClassAPI, ClassAPI refClassAPI) |
| { |
| List currMethodAPIs = new ArrayList(currClassAPI.getMethodAPIs()); |
| List refMethodAPIs = new ArrayList(refClassAPI.getMethodAPIs()); |
| for (int i = 0; i < currMethodAPIs.size(); i++) |
| { |
| MethodAPI currMethodAPI = (MethodAPI)currMethodAPIs.get(i); |
| for (int j = 0; j < refMethodAPIs.size(); j++) |
| { |
| MethodAPI refMethodAPI = (MethodAPI)refMethodAPIs.get(j); |
| if (currMethodAPI.getName().equals(refMethodAPI.getName()) && currMethodAPI.getDescriptor().equals(refMethodAPI.getDescriptor())) |
| { |
| currClassAPI.removeMethodAPI(currMethodAPI); |
| refClassAPI.removeMethodAPI(refMethodAPI); |
| break; |
| } |
| } |
| } |
| List currFieldAPIs = new ArrayList(currClassAPI.getFieldAPIs()); |
| List refFieldAPIs = new ArrayList(refClassAPI.getFieldAPIs()); |
| for (int i = 0; i < currFieldAPIs.size(); i++) |
| { |
| FieldAPI currFieldAPI = (FieldAPI)currFieldAPIs.get(i); |
| for (int j = 0; j < refFieldAPIs.size(); j++) |
| { |
| FieldAPI refFieldAPI = (FieldAPI)refFieldAPIs.get(j); |
| if (currFieldAPI.getName().equals(refFieldAPI.getName()) && currFieldAPI.getDescriptor().equals(refFieldAPI.getDescriptor())) |
| { |
| currClassAPI.removeFieldAPI(currFieldAPI); |
| refClassAPI.removeFieldAPI(refFieldAPI); |
| break; |
| } |
| } |
| } |
| } |
| |
| private void genHTML() |
| { |
| final StringBuffer summary = new StringBuffer(); |
| summary.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>"); |
| summary.append("<root>"); |
| ILocation outputLoc = Location.createLocation(new File(outputDir)); |
| outputLoc.accept(new ILocationVisitor() |
| { |
| public boolean accept(ILocation location) |
| { |
| if (location.getName().endsWith("api-comp.xml")) |
| { |
| try |
| { |
| XSLUtil.transform |
| ( |
| xsl != null && xsl.length() > 0 ? Location.createLocation(new File(xsl)).getInputStream() : ClassLoader.getSystemResourceAsStream("org/eclipse/wtp/releng/tools/component/xsl/api-comp.xsl"), |
| location.getInputStream(), |
| new FileOutputStream(((FileLocation)location.createSibling("api-comp.html")).getFile()) |
| ); |
| summary.append("<api-comp file=\""); |
| summary.append(location.getAbsolutePath().substring(outputDir.length())); |
| summary.append("\"/>"); |
| } |
| catch (Throwable e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| return true; |
| } |
| }); |
| summary.append("</root>"); |
| try |
| { |
| XSLUtil.transform |
| ( |
| ClassLoader.getSystemResourceAsStream("org/eclipse/wtp/releng/tools/component/xsl/api-comp-summary.xsl"), |
| new ByteArrayInputStream(summary.toString().getBytes()), |
| new FileOutputStream(new File(outputDir + "/api-comp-summary.html")), |
| outputDir |
| ); |
| } |
| catch (Throwable e) |
| { |
| e.printStackTrace(); |
| } |
| } |
| |
| protected static String addTrailingSeperator(String s) |
| { |
| if (s != null && !s.endsWith("/") && !s.endsWith("\\")) |
| { |
| StringBuffer sb = new StringBuffer(s); |
| sb.append('/'); |
| return sb.toString(); |
| } |
| else |
| { |
| return s; |
| } |
| } |
| |
| public static void main(String[] args) |
| { |
| CommandOptionParser optionParser = new CommandOptionParser(args); |
| Map options = optionParser.getOptions(); |
| Collection api = (Collection)options.get("api"); |
| Collection src = (Collection)options.get("src"); |
| Collection refapi = (Collection)options.get("refapi"); |
| Collection refsrc = (Collection)options.get("refsrc"); |
| Collection outputDir = (Collection)options.get("outputDir"); |
| Collection includes = (Collection)options.get("includes"); |
| Collection excludes = (Collection)options.get("excludes"); |
| Collection html = (Collection)options.get("html"); |
| Collection xsl = (Collection)options.get("xsl"); |
| if (src == null || api == null || outputDir == null || src.isEmpty() || api.isEmpty() || outputDir.isEmpty()) |
| { |
| printUsage(); |
| System.exit(-1); |
| } |
| String od = addTrailingSeperator((String)outputDir.iterator().next()); |
| String currOutputDir = od + "1/"; |
| String refOutputDir = od + "2/"; |
| API2ComponentAPI api2CompAPI = new API2ComponentAPI(); |
| api2CompAPI.setApi(api); |
| api2CompAPI.setSrc(src); |
| api2CompAPI.setOutputDir(currOutputDir); |
| api2CompAPI.setIncludes(includes); |
| api2CompAPI.setExcludes(excludes); |
| api2CompAPI.execute(); |
| api2CompAPI = new API2ComponentAPI(); |
| api2CompAPI.setApi(refapi); |
| api2CompAPI.setSrc(refsrc); |
| api2CompAPI.setOutputDir(refOutputDir); |
| api2CompAPI.setIncludes(includes); |
| api2CompAPI.setExcludes(excludes); |
| api2CompAPI.execute(); |
| APICompatibilityScanner scanner = new APICompatibilityScanner(); |
| scanner.setOutputDir((String)outputDir.iterator().next()); |
| scanner.setHtml(html != null); |
| scanner.setXsl(xsl != null && !xsl.isEmpty() ? (String)xsl.iterator().next() : null); |
| scanner.execute(); |
| } |
| |
| private static void printUsage() |
| { |
| System.out.println("Usage: java org.eclipse.wtp.releng.tools.component.api.compatibility.APICompatibilityScanner -api <api> -src <src> -refapi <refapi> -refsrc <refsrc> -outputDir <outputDir> [-options]"); |
| System.out.println(""); |
| System.out.println("\t-api\t\t<api>\t\tlocation of your component.xml"); |
| System.out.println("\t-src\t\t<src>\t\tlocation of your Eclipse-based product"); |
| System.out.println("\t-refapi\t\t<refapi>\t\tlocation of your reference component.xml"); |
| System.out.println("\t-refsrc\t\t<refsrc>\t\tlocation of your reference Eclipse-based product"); |
| System.out.println("\t-outputDir\t<outputDir>\toutput directory"); |
| System.out.println(""); |
| System.out.println("where options include:"); |
| System.out.println(""); |
| System.out.println("\t-includes\t<includes>\tspace seperated packages to include"); |
| System.out.println("\t-excludes\t<excludes>\tspace seperated packages to exclude"); |
| System.out.println("\t-html\t\t\t\tgenerate HTML results"); |
| System.out.println("\t-xsl\t<xsl>\t\tuse your own stylesheet. You must specify the -html option"); |
| } |
| } |