blob: 9dfce6f71590e2131a27fe5e9c3f3e6683295aa6 [file] [log] [blame]
/*******************************************************************************
* Copyright (c) 2004, 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.adopters;
import java.io.ByteArrayInputStream;
import java.io.CharArrayWriter;
import java.io.File;
import java.io.FileOutputStream;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.Collection;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import org.eclipse.core.runtime.IPlatformRunnable;
import org.eclipse.core.runtime.Platform;
import org.eclipse.jdt.core.dom.AST;
import org.eclipse.jdt.core.dom.ASTNode;
import org.eclipse.jdt.core.dom.ASTParser;
import org.eclipse.wtp.releng.tools.component.CommandOptionParser;
import org.eclipse.wtp.releng.tools.component.IJavaVisitor;
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.ComponentAPI;
import org.eclipse.wtp.releng.tools.component.api.ComponentXMLVisitor;
import org.eclipse.wtp.releng.tools.component.images.ImagesUtil;
import org.eclipse.wtp.releng.tools.component.internal.ComponentXML;
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.internal.Package;
import org.eclipse.wtp.releng.tools.component.internal.Plugin;
import org.eclipse.wtp.releng.tools.component.internal.Type;
import org.eclipse.wtp.releng.tools.component.xsl.XSLUtil;
public class JavadocScanner implements IJavaVisitor, IPlatformRunnable
{
private Collection src;
private String api;
private String outputDir;
private Collection includes;
private Collection excludes;
private boolean skipAPIGen;
private boolean html;
private String xsl;
public String getOutputDir()
{
return outputDir;
}
public void setOutputDir(String outputDir)
{
this.outputDir = addTrailingSeperator(outputDir);
}
public Collection getSrc()
{
return src;
}
public void setSrc(Collection src)
{
this.src = src;
}
public String getApi()
{
return api;
}
public void setApi(String api)
{
this.api = api;
}
public Collection getIncludes()
{
return includes;
}
public void setIncludes(Collection includes)
{
this.includes = includes;
}
public Collection getExcludes()
{
return excludes;
}
public void setExcludes(Collection excludes)
{
this.excludes = excludes;
}
public boolean isSkipAPIGen()
{
return skipAPIGen;
}
public void setSkipAPIGen(boolean skipAPIGen)
{
this.skipAPIGen = skipAPIGen;
}
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 Map pluginId2CompXML = new HashMap();
public void execute()
{
// Generate api-info.xml
if (!skipAPIGen)
{
API2ComponentAPI api2CompXML = new API2ComponentAPI();
api2CompXML.setApi(api);
api2CompXML.setSrc(src);
api2CompXML.setOutputDir(outputDir);
api2CompXML.setIncludes(includes);
api2CompXML.setExcludes(excludes);
api2CompXML.setReadInterface(true);
api2CompXML.setSkipAPIGen(skipAPIGen);
api2CompXML.execute();
}
// Collection component.xml files
ILocation apiLocation = Location.createLocation(new File(api));
ComponentXMLVisitor compXMLVisitor = new ComponentXMLVisitor();
apiLocation.accept(compXMLVisitor);
for (Iterator it = compXMLVisitor.getCompXMLs().iterator(); it.hasNext();)
{
ComponentXML compXML = (ComponentXML)it.next();
for (Iterator it2 = compXML.getPlugins().iterator(); it2.hasNext();)
{
pluginId2CompXML.put(((Plugin)it2.next()).getId(), compXML);
}
}
// visit .java
scanJavaSources();
// Save report
try
{
if (cachedCompAPI != null)
cachedCompAPI.save();
}
catch (IOException e)
{
throw new RuntimeException(e);
}
if (isHtml())
{
ImagesUtil.copyAllFromBundle(Platform.getBundle("org.eclipse.wtp.releng.tools.component.core"), outputDir);
genHTML();
}
}
protected void scanJavaSources()
{
for (Iterator it = src.iterator(); it.hasNext();)
{
ILocation srcLocation = Location.createLocation(new File((String)it.next()));
PDESourceVisitor pdeSrcVisitor = new PDESourceVisitor();
srcLocation.accept(pdeSrcVisitor);
pdeSrcVisitor.setJavaVisitor(this);
srcLocation.accept(pdeSrcVisitor);
}
}
private void genHTML()
{
final StringBuffer summary = new StringBuffer();
summary.append("<?xml version=\"1.0\" encoding=\"UTF-8\"?>");
summary.append("<root>");
File f = new File(outputDir);
f.mkdirs();
ILocation outputLoc = Location.createLocation(f);
outputLoc.accept(new ILocationVisitor()
{
public boolean accept(ILocation location)
{
if (location.getName().endsWith("api-info.xml"))
{
try
{
XSLUtil.transform
(
xsl != null && xsl.length() > 0 ? Location.createLocation(new File(xsl)).getInputStream() : Platform.getBundle("org.eclipse.wtp.releng.tools.component.core").getResource("org/eclipse/wtp/releng/tools/component/xsl/api-javadoc.xsl").openStream(),
location.getInputStream(),
new FileOutputStream(((FileLocation)location.createSibling("api-javadoc.html")).getFile())
);
summary.append("<api-info file=\"");
summary.append(location.getAbsolutePath().substring(outputDir.length()));
summary.append("\"/>");
}
catch (Throwable e)
{
e.printStackTrace();
}
}
return true;
}
}
);
summary.append("</root>");
try
{
XSLUtil.transform
(
Platform.getBundle("org.eclipse.wtp.releng.tools.component.core").getResource("org/eclipse/wtp/releng/tools/component/xsl/api-javadoc-summary.xsl").openStream(),
new ByteArrayInputStream(summary.toString().getBytes()),
new FileOutputStream(new File(outputDir + "/api-javadoc-summary.html")),
outputDir
);
}
catch (Throwable e)
{
e.printStackTrace();
}
}
protected ASTParser astParser;
public boolean visit(String pluginId, ILocation java)
{
String name = java.getName();
if (include(name) && isAPI(pluginId, name))
{
try
{
ComponentAPI compAPI = getComponentAPI(pluginId);
InputStreamReader isr = new InputStreamReader(java.getInputStream());
CharArrayWriter caw = new CharArrayWriter();
char[] c = new char[2048];
for (int read = isr.read(c); read != -1; read = isr.read(c))
caw.write(c, 0, read);
isr.close();
caw.close();
if (astParser == null)
astParser = ASTParser.newParser(AST.JLS3);
astParser.setSource(caw.toCharArray());
ASTNode node = astParser.createAST(null);
node.accept(new JavadocVisitor(compAPI, pluginId));
}
catch (IOException e)
{
throw new RuntimeException(e);
}
}
return true;
}
protected boolean isAPI(String pluginId, String name)
{
ComponentXML compXML = (ComponentXML)pluginId2CompXML.get(pluginId);
if (compXML != null)
{
name = name.substring(0, name.length() - ".java".length());
name = name.replace('/', '.');
name = name.replace('\\', '.');
int i = name.lastIndexOf('.');
String packageName = (i != -1) ? name.substring(0, i) : "";
String localName = (i != -1) ? name.substring(i + 1) : name;
Package pkg = compXML.getPackage(packageName);
if (pkg != null)
{
Type type = pkg.getType(localName);
if (type != null)
{
return type.isReference() || type.isSubclass() || type.isImplement() || type.isInstantiate();
}
else
{
return pkg.isApi();
}
}
}
return false;
}
protected boolean include(String name)
{
name = name.replace('/', '.');
name = name.replace('\\', '.');
if (excludes != null && !excludes.isEmpty())
for (Iterator it = excludes.iterator(); it.hasNext();)
if (name.matches((String)it.next()))
return false;
if (includes != null && !includes.isEmpty())
{
for (Iterator it = includes.iterator(); it.hasNext();)
if (name.matches((String)it.next()))
return true;
return false;
}
return true;
}
private ComponentAPI cachedCompAPI;
protected ComponentAPI getComponentAPI(String id) throws IOException
{
if (cachedCompAPI != null)
{
if (cachedCompAPI.getName().equals(id))
{
return cachedCompAPI;
}
else
{
cachedCompAPI.save();
}
}
StringBuffer sb = new StringBuffer(outputDir);
sb.append(id);
sb.append("/api-info.xml");
File file = new File(sb.toString());
cachedCompAPI = new ComponentAPI();
cachedCompAPI.setName(id);
cachedCompAPI.setLocation(new FileLocation(file));
if (file.exists())
cachedCompAPI.load();
return cachedCompAPI;
}
protected 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 Object run(Object arguments)
{
String src = System.getProperty("src");
String api = System.getProperty("api");
String outputDir = System.getProperty("outputDir");
String includes = System.getProperty("includes");
String excludes = System.getProperty("excludes");
String skipAPIGen = System.getProperty("skipAPIGen");
String html = System.getProperty("html");
String xsl = System.getProperty("xsl");
main(new String[]{"-src", src, "-api", api, "-outputDir", outputDir, "-includes", includes, "-excludes", excludes, skipAPIGen != null ? "-skipAPIGen" : "", html != null ? "-html" : "", "-xsl", xsl});
return IPlatformRunnable.EXIT_OK;
}
public static void main(String[] args)
{
CommandOptionParser optionParser = new CommandOptionParser(args);
Map options = optionParser.getOptions();
Collection src = (Collection)options.get("src");
Collection api = (Collection)options.get("api");
Collection outputDir = (Collection)options.get("outputDir");
Collection includes = (Collection)options.get("includes");
Collection excludes = (Collection)options.get("excludes");
Collection skipAPIGen = (Collection)options.get("skipAPIGen");
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);
}
JavadocScanner javadocScanner = new JavadocScanner();
javadocScanner.setSrc(src);
javadocScanner.setApi((String)api.iterator().next());
javadocScanner.setOutputDir((String)outputDir.iterator().next());
javadocScanner.setIncludes(includes);
javadocScanner.setExcludes(excludes);
javadocScanner.setSkipAPIGen(skipAPIGen != null);
javadocScanner.setHtml(html != null);
javadocScanner.setXsl(xsl != null && !xsl.isEmpty() ? (String)xsl.iterator().next() : null);
javadocScanner.execute();
}
protected static void printUsage()
{
System.out.println("Usage: java org.eclipse.wtp.releng.tools.component.java.JavadocScanner -src <src> -api <api> -outputDir <outputDir> [-options]");
System.out.println("");
System.out.println("\t-src\t\t<src>\t\tlocation of a Eclipse-based product (requires SDK build)");
System.out.println("\t-api\t\t<api>\t\tlocation of your component.xml");
System.out.println("\t-outputDir\t<outputDir>\toutput directory of component.xml files");
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-skipAPIGen\t\t\tskip api-info.xml generation and use existing ones");
System.out.println("\t-html\t\t\tgenerate HTML results");
System.out.println("\t-xsl\t<xsl>\tuse your own stylesheet. You must specify the -html option");
}
}