| /******************************************************************************* |
| * 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"); |
| } |
| } |