blob: b9f0797814762958fc974ccb423d47305e31f3b8 [file] [log] [blame]
/*******************************************************************************
* 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");
}
}