blob: 59da2192c0a31a8f3ba424120be45c98376fc678 [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 Common Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/cpl-v10.html
 *
* Contributors:
* IBM - Initial API and implementation
**********************************************************************/
package org.eclipse.wtp.releng.tools.component.api.testcoverage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import org.eclipse.jdt.core.util.IModifierConstants;
import org.eclipse.wtp.releng.tools.component.ILocation;
import org.eclipse.wtp.releng.tools.component.api.APIs;
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.ComponentAPIEmitter;
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.api.testcoverage.MethodAPITestCoverage;
import org.eclipse.wtp.releng.tools.component.api.testcoverage.Testcase;
import org.eclipse.wtp.releng.tools.component.internal.AbstractEmitter;
import org.eclipse.wtp.releng.tools.component.internal.ComponentEntry;
import org.eclipse.wtp.releng.tools.component.internal.ComponentSummary;
import org.eclipse.wtp.releng.tools.component.internal.FileLocation;
import org.eclipse.wtp.releng.tools.component.model.ComponentXML;
import org.eclipse.wtp.releng.tools.component.model.Package;
import org.eclipse.wtp.releng.tools.component.use.ClassUse;
import org.eclipse.wtp.releng.tools.component.use.ComponentUse;
import org.eclipse.wtp.releng.tools.component.use.ComponentUseEmitter;
import org.eclipse.wtp.releng.tools.component.use.MethodUse;
import org.eclipse.wtp.releng.tools.component.use.Source;
import org.eclipse.wtp.releng.tools.component.util.CommandOptionParser;
public class APITestCoverageEmitter extends AbstractEmitter
{
public static final String CONST_COMPONENT_API_TEST_COVERAGE_XML = "component-api-tc.xml";
public static final String CONST_COMPONENT_API_TEST_COVERAGE_HTML = "component-api-tc.html";
public static final String OPTION_ECLIPSE_DIR = "eclipseDir";
public static final String OPTION_TEST_DIR = "testDir";
public static final String OPTION_COMPONENT_XML_DIR = "compXMLDir";
public static final String OPTION_COMPONENT_API_DIR = "compAPIDir";
public static final String OPTION_GEN_HTML = "genHTML";
public static final String OPTION_GEN_API = "genAPI";
private String compAPIDir;
private Map id2Plugin;
private Map id2Fragment;
private Map id2TestPlugin;
private Map id2TestFragment;
private Map compLoc2CompXML;
private boolean genHTML;
private boolean genAPI;
private ComponentAPIEmitter compAPIEmitter;
public APITestCoverageEmitter(String compAPIDir)
{
this.compAPIDir = addTrailingSeperator(compAPIDir);
genHTML = false;
genAPI = false;
}
public void init(List eclipseDirs, List testDirs, List compXMLDirs)
{
id2Plugin = new HashMap();
id2Fragment = new HashMap();
for (Iterator it = eclipseDirs.iterator(); it.hasNext();)
{
File eclipseFile = new File(addTrailingSeperator((String)it.next()));
if (eclipseFile.exists())
harvestPlugins(eclipseFile, id2Plugin, id2Fragment);
}
linkPluginsAndFragments(id2Plugin, id2Fragment);
id2TestPlugin = new HashMap();
id2TestFragment = new HashMap();
for (Iterator it = testDirs.iterator(); it.hasNext();)
{
File testFile = new File(addTrailingSeperator((String)it.next()));
if (testFile.exists())
harvestPlugins(testFile, id2TestPlugin, id2TestFragment);
}
linkPluginsAndFragments(id2TestPlugin, id2TestFragment);
compLoc2CompXML = new HashMap();
for (Iterator it = compXMLDirs.iterator(); it.hasNext();)
{
File compXMLFile = new File(addTrailingSeperator((String)it.next()));
if (compXMLFile.exists())
harvestComponents(compXMLFile, compLoc2CompXML);
}
init();
}
public void init(Map compLoc2CompXML, Map id2Plugin, Map id2Fragment, Map id2TestPlugin, Map id2TestFragment)
{
this.compLoc2CompXML = compLoc2CompXML;
this.id2Plugin = id2Plugin;
this.id2Fragment = id2Fragment;
this.id2TestPlugin = id2TestPlugin;
this.id2TestFragment = id2TestFragment;
init();
}
private void init()
{
compAPIEmitter = new ComponentAPIEmitter(genAPI ? compAPIDir : null);
compAPIEmitter.init(compLoc2CompXML, id2Plugin, id2Fragment);
}
/**
* @return Returns the genHTML.
*/
public boolean isGenHTML()
{
return genHTML;
}
/**
* @param genHTML The genHTML to set.
*/
public void setGenHTML(boolean genHTML)
{
this.genHTML = genHTML;
}
public boolean getGenAPI()
{
return genAPI;
}
public void setGenAPI(boolean genAPI)
{
this.genAPI = genAPI;
}
public void genAPITestCoverageXML() throws IOException
{
ComponentSummary compSummary = genAPI ? new ComponentSummary() : null;
APITestCoverageSummary summary = new APITestCoverageSummary();
List includes = new ArrayList();
for (Iterator it = compLoc2CompXML.values().iterator(); it.hasNext();)
harvestPackages((ComponentXML)it.next(), includes);
ComponentUseEmitter compUseEmitter = newComponentUseEmitter(id2TestPlugin, id2TestFragment, includes);
ComponentUse compUse = compUseEmitter.genAll();
for (Iterator it = compLoc2CompXML.keySet().iterator(); it.hasNext();)
{
String compLoc = (String)it.next();
ComponentAPI compAPI = compAPIEmitter.genComponentApiXml(compLoc);
compAPI.save();
if (genAPI)
{
ComponentEntry entry = new ComponentEntry();
entry.setCompName(compAPI.getName());
entry.setRef(compAPI.getLocation().getAbsolutePath());
compSummary.add(entry);
}
summary.add(genAPITestCoverageXML(compLoc, compUse, compAPI));
}
if (compAPIDir != null)
{
if (genAPI)
compSummary.save(new FileLocation(new File(compAPIDir + ComponentSummary.INDEX_COMPONENT_SUMMARY_XML)));
summary.save(new FileLocation(new File(compAPIDir + "index-api-tc.xml")));
if (genHTML)
{
try
{
summary.saveAsHTML(new FileLocation(new File(compAPIDir + "index-api-tc.html")));
}
catch (TransformerConfigurationException e)
{
e.printStackTrace();
}
catch (TransformerException e)
{
e.printStackTrace();
}
}
}
}
public ComponentAPI genAPITestCoverageXML(String compLoc) throws IOException
{
List includes = new ArrayList();
ComponentXML componentXML = (ComponentXML)compLoc2CompXML.get(compLoc);
if (componentXML != null)
harvestPackages(componentXML, includes);
ComponentUseEmitter compUseEmitter = newComponentUseEmitter(id2TestPlugin, id2TestFragment, includes);
ComponentUse compUse = compUseEmitter.genAll();
ComponentAPI compAPI = compAPIEmitter.genComponentApiXml(compLoc);
compAPI.save();
return genAPITestCoverageXML(compLoc, compUse, compAPI);
}
private ComponentAPI genAPITestCoverageXML(String compLoc, ComponentUse compUse, ComponentAPI compAPI) throws IOException
{
ComponentXML componentXML = (ComponentXML)compLoc2CompXML.get(compLoc);
if (componentXML != null)
{
componentXML.load();
APIs apis = compAPI.getExternalAPIs();
List pkgAPIs = apis.getPackageAPIs();
for (int i = 0; i < pkgAPIs.size(); i++)
{
PackageAPI pkgAPI = (PackageAPI)pkgAPIs.get(i);
List classAPIs = pkgAPI.getClassAPIs();
for (int j = 0; j < classAPIs.size(); j++)
{
ClassAPI classAPI = (ClassAPI)classAPIs.get(j);
int classAccess = classAPI.getAccess();
if (!isBit(classAccess, IModifierConstants.ACC_PUBLIC) || isBit(classAccess, IModifierConstants.ACC_INTERFACE) || !classAPI.isReference())
{
// We don't need test coverage for non-public classes, interfaces,
// classes that cannot be referenced.
classAPIs.remove(j);
j--;
}
else
{
classAPI.getFieldAPIs().clear();
List methodAPIs = classAPI.getMethodAPIs();
List methodApiTcs = new ArrayList(methodAPIs.size());
for (Iterator it = methodAPIs.iterator(); it.hasNext();)
{
MethodAPI methodAPI = (MethodAPI)it.next();
methodApiTcs.add(newMethodAPITestCoverage(methodAPI, getTestcases(compUse, classAPI.getName(), methodAPI)));
}
methodAPIs.clear();
methodAPIs.addAll(methodApiTcs);
if (methodAPIs.size() == 0)
{
// We don't need test coverage for classes with no API methods.
classAPIs.remove(j);
j--;
}
}
}
if (classAPIs.size() == 0)
{
pkgAPIs.remove(i);
i--;
}
}
if (compAPIDir != null)
{
String compName = componentXML.getName();
StringBuffer sb = new StringBuffer(compAPIDir);
sb.append(compName);
sb.append('/');
ILocation location = new FileLocation(new File(sb.toString() + CONST_COMPONENT_API_TEST_COVERAGE_XML));
compAPI.setLocation(location);
System.out.println("Writing component-api-tc.xml for " + compName);
compAPI.save();
if (genHTML)
{
try
{
ILocation html = new FileLocation(new File(sb.toString() + CONST_COMPONENT_API_TEST_COVERAGE_HTML));
compAPI.setLocation(html);
compAPI.saveAsHTML(html, "org/eclipse/wtp/releng/tools/component/xsl/component-api-tc.xsl");
copyImages();
}
catch (TransformerConfigurationException e)
{
e.printStackTrace();
}
catch (TransformerException e)
{
e.printStackTrace();
}
}
}
}
return compAPI;
}
private void harvestPackages(ComponentXML compXML, List includes) throws IOException
{
compXML.load();
List pkgs = compXML.getPackages();
for (Iterator it = pkgs.iterator(); it.hasNext();)
{
String pkgName = ((Package)it.next()).getName();
if (!includes.contains(pkgName))
includes.add(pkgName);
}
}
private ComponentUseEmitter newComponentUseEmitter(Map plugins, Map fragments, List includes)
{
ComponentUseEmitter compUseEmitter = new ComponentUseEmitter(null);
compUseEmitter.setDebug(false);
compUseEmitter.setClassUseIncludes(includes);
compUseEmitter.init(new HashMap(0), plugins, fragments);
return compUseEmitter;
}
private boolean isBit(int flag, int bit)
{
return ((flag & bit) == bit);
}
private MethodAPITestCoverage newMethodAPITestCoverage(MethodAPI methodAPI, List testcases)
{
MethodAPITestCoverage methodAPITestCoverage = new MethodAPITestCoverage();
methodAPITestCoverage.setName(methodAPI.getName());
methodAPITestCoverage.setDescriptor(methodAPI.getDescriptor());
methodAPITestCoverage.setAccess(methodAPI.getAccess());
methodAPITestCoverage.setTestcases(testcases);
return methodAPITestCoverage;
}
private List getTestcases(ComponentUse compUse, String className, MethodAPI methodAPI)
{
List testcases = new ArrayList();
for (Iterator sourcesIt = compUse.getSources().iterator(); sourcesIt.hasNext();)
{
Source source = (Source)sourcesIt.next();
for (Iterator classUsesIt = source.getClassUses().iterator(); classUsesIt.hasNext();)
{
ClassUse classUse = (ClassUse)classUsesIt.next();
if (classUse.getName().equals(className))
{
for (Iterator methodUsesIt = classUse.getMethodUses().iterator(); methodUsesIt.hasNext();)
{
MethodUse methodUse = (MethodUse)methodUsesIt.next();
if (methodUse.getName().equals(methodAPI.getName()) && methodUse.getDescriptor().equals(methodAPI.getDescriptor()))
{
Testcase testcase = new Testcase();
testcase.setClassName(source.getName());
testcases.add(testcase);
}
}
}
}
}
return testcases;
}
private void copyImages()
{
StringBuffer outputDir = new StringBuffer(compAPIDir).append('/');
File ok = new File(outputDir.toString() + "OK.gif");
if (!ok.exists())
{
try
{
InputStream is = ClassLoader.getSystemResourceAsStream("org/eclipse/wtp/releng/tools/component/images/OK.gif");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(ok));
copy(is, bos);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
File fail = new File(outputDir.toString() + "FAIL.gif");
if (!fail.exists())
{
try
{
InputStream is = ClassLoader.getSystemResourceAsStream("org/eclipse/wtp/releng/tools/component/images/FAIL.gif");
BufferedOutputStream bos = new BufferedOutputStream(new FileOutputStream(fail));
copy(is, bos);
}
catch (FileNotFoundException e)
{
e.printStackTrace();
}
}
}
private void copy(InputStream is, OutputStream os)
{
try
{
byte[] b = new byte[2048];
int read = is.read(b);
while (read != -1)
{
os.write(b, 0, read);
read = is.read(b);
}
}
catch (IOException e)
{
e.printStackTrace();
}
finally
{
try
{
os.close();
}
catch (IOException e)
{
e.printStackTrace();
}
try
{
is.close();
}
catch (IOException e)
{
e.printStackTrace();
}
}
}
public static void main(String[] args)
{
CommandOptionParser optionParser = new CommandOptionParser(args);
Map options = optionParser.getOptions();
List eclipseDir = (List)options.get(APITestCoverageEmitter.OPTION_ECLIPSE_DIR);
List testDir = (List)options.get(APITestCoverageEmitter.OPTION_TEST_DIR);
List compXMLDir = (List)options.get(APITestCoverageEmitter.OPTION_COMPONENT_XML_DIR);
List compAPIDir = (List)options.get(APITestCoverageEmitter.OPTION_COMPONENT_API_DIR);
List genHTML = (List)options.get(APITestCoverageEmitter.OPTION_GEN_HTML);
List genAPI = (List)options.get(APITestCoverageEmitter.OPTION_GEN_API);
if (eclipseDir == null || testDir == null || compXMLDir == null || compAPIDir == null || eclipseDir.size() < 1 || testDir.size() < 1 || compXMLDir.size() < 1 || compAPIDir.size() < 1)
{
printUsage();
System.exit(-1);
}
APITestCoverageEmitter apiTestCoverageEmitter = new APITestCoverageEmitter((String)compAPIDir.get(0));
apiTestCoverageEmitter.setGenHTML(genHTML != null);
apiTestCoverageEmitter.setGenAPI(genAPI != null);
apiTestCoverageEmitter.init(eclipseDir, testDir, compXMLDir);
try
{
apiTestCoverageEmitter.genAPITestCoverageXML();
}
catch (IOException ioe)
{
ioe.printStackTrace();
}
}
private static void printUsage()
{
System.out.println("Usage: java org.eclipse.wtp.releng.tools.component.api.testcoverage.APITestCoverageEmitter -eclipseDir <eclipseDir> -testDir <testDir> -compXMLDir <compXMLDir> -compAPIDir <compAPIDir> [-options]");
System.out.println("");
System.out.println("\t-eclipseDir\t<eclipseDir>\tspace seperated list of directories containing Eclipse plugins");
System.out.println("\t-testDir\t<testDir>\tspace separated list of directories containing test plugins");
System.out.println("\t-compXMLDir\t<compXMLDir>\tdirectories containing component.xml that will be checked for API test coverage");
System.out.println("\t-compAPIDir\t<compVioDir>\toutput directory of component-api-tc.xml");
System.out.println("");
System.out.println("where options include:");
System.out.println("");
System.out.println("\t-genHTML\tgenerate test coverage report in HTML");
System.out.println("\t-genAPI\t\tgenerate component-api.xml");
}
}